java8新特性学习2
六、Stream API
Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API(java.util.stream.*)。Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式
流(Stream) 到底是什么呢?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算!”
注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。(也就是中间操作不会立即执行)
Stream操作分为三个步骤
1、创建 Stream一个数据源(如:集合、数组),获取一个流
2、中间操作一个中间操作链,对数据源的数据进行处理
3、终止操作(终端操作)一个终止操作,执行中间操作链,并产生结果
步骤一:创建Stream的四种方式
- package com.bjsxt.stream;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.stream.Stream;
- /**
- * stream的三个步骤
- * 1、创建stream
- * 2、中间操作
- * 3、终止操作(终端操作)
- */
- public class TestStream01 {
- public static void main(String[] args){
- test01();
- }
- /**
- * 创建stream的四种方式
- */
- public static void test01(){
- // 1、可以通过Collection系列集合提供的stream()或parallelStream()
- List<String> list=new ArrayList<String>();
- Stream<String> stream=list.stream();
- // 2、可以通过Arrays中的静态方法stream()获取数据流
- String[] strArr=new String[10];
- Stream<String> stream2=Arrays.stream(strArr);
- // 3、通过Stream类中的静态方法of()
- Stream<String> stream3=Stream.of("aa","bb","cc");
- // 4、创建无限流
- //方式一:迭代,使用Stream.iterate()方法
- Stream<Integer> stream4=Stream.iterate(0,(x)->x+2);
- //方式二:生成,使用Stream.generate()方法
- Stream<Double> stream5=Stream.generate(()->Math.random());
- stream5.forEach(System.out::println); //这个forEach()方法是终端操作,打印用
- }
- }
步骤二:中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。
中间操作有很多种,主要有三种
1、筛选与切片
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.Arrays;
- import java.util.List;
- import java.util.stream.Stream;
- /**
- * stream
- * 中间操作
- */
- public class TestStream02 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- }
- /**
- * filter()方法
- */
- public static void tesst01(){
- Stream<Person> stream=list.stream(); //获取流
- stream.filter((per)->per.age>18) //filter()接收 Lambda , 从流中排除某些元素,会进行隐式迭代
- .forEach(System.out::println); //这个是终端操作,这里使用只是方便打印
- }
- /**
- * limit()方法
- */
- public static void tesst02(){
- Stream<Person> stream=list.stream(); //获取流
- stream.filter((per)->per.age>18) //filter()接收 Lambda , 从流中排除某些元素
- .limit(2) //截断流,使其元素不超过给定数量。也就是只要筛选出来的前两个,这里操作类似于短路(&&),当筛选出来两个后,后面的就不再迭代,提高效率
- .forEach(System.out::println); //这个是终端操作,这里使用只是方便打印
- }
- /**
- * skip()方法
- */
- public static void tesst03(){
- Stream<Person> stream=list.stream(); //获取流
- stream.filter((per)->per.age>18) //filter()接收 Lambda , 从流中排除某些元素
- .skip(2) //跳过前两个元素,跟limit刚好相反
- .forEach(System.out::println); //这个是终端操作,这里使用只是方便打印
- }
- /**
- *distinct()方法
- */
- public static void tesst04(){
- Stream<Person> stream=list.stream(); //获取流
- stream.filter((per)->per.age>18) //filter()接收 Lambda , 从流中排除某些元素
- .distinct() //筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素
- .forEach(System.out::println); //这个是终端操作,这里使用只是方便打印
- }
- }
2、映射
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.stream.Stream;
- /**
- * stream
- * 中间操作
- */
- public class TestStream03 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- tesst02();
- }
- /**
- * map()方法
- */
- public static void tesst01(){
- Stream<Person> stream=list.stream(); //获取流
- stream.map((person -> person.getName())) //接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
- .forEach(System.out::println);
- System.out.println("-----------------------------------------------------------------------------");
- List<String> list=Arrays.asList("aa","bb","cc");
- list.stream().map(str->str.toUpperCase())
- .forEach(System.out::println);
- }
- /**
- * flatMap()方法
- */
- public static void tesst02(){
- List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
- Stream<Stream<Character>> stream=strList.stream().map(TestStream03::splitString);
- stream.forEach(sm->sm.forEach(System.out::println)); //如果使用map需要这样遍历
- System.out.println("------------------------------");
- /**
- * map和flatMap的区别就如集合中add(集合)和addAll(集合)的区别
- */
- Stream<Character> stream2 = strList.stream()
- .flatMap(TestStream03::splitString); //接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
- stream2.forEach(System.out::println);
- }
- public static Stream<Character> splitString(String str){
- List<Character> list=new ArrayList<Character>();
- for(Character c:str.toCharArray()){
- list.add(c);
- }
- return list.stream();
- }
- }
3、排序
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.stream.Stream;
- /**
- * stream
- * 中间操作
- */
- public class TestStream04 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- tesst02();
- }
- /**
- * sorted()方法,按照自然顺序排序
- */
- public static void tesst01(){
- List<String> list=Arrays.asList("bb","aa","dd","ee");
- list.stream()
- .sorted()
- .forEach(System.out::println);
- }
- /**
- * sorted(Comparator<? super T> comparator)方法,需要传一个比较器过去,按照指定的比较器进行排序
- */
- public static void tesst02(){
- list.stream().sorted((e1,e2)->{
- if(e1.age==e2.age){
- return e1.name.compareTo(e2.name);
- }else{
- return e1.age.compareTo(e2.age);
- }
- }).forEach(System.out::println);
- }
- }
步骤三:终止操作
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void,终止操作也有多种
1、查找与匹配
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Optional;
- /**
- * stream
- * 终止操作
- */
- public class TestStream05 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- tesst01();
- }
- /**
- * 终止操作
- * allMatch——检查是否匹配所有元素
- * anyMatch——检查是否至少匹配一个元素
- * noneMatch——检查是否没有匹配的元素
- * findFirst——返回第一个元素
- * findAny——返回当前流中的任意元素
- * count——返回流中元素的总个数
- * max——返回流中最大值
- * min——返回流中最小值
- */
- public static void tesst01(){
- boolean b1=list.stream().allMatch(person -> person.getAge()>10); //是否所有人的年龄大于10
- System.out.println(b1);
- boolean b2=list.stream().anyMatch(person -> person.getAge()>100); //是否至少一个人的年龄大于100
- System.out.println(b2);
- boolean b3=list.stream().noneMatch(person -> person.getAge()>100); //没有一个人的年龄大于100
- System.out.println(b3);
- Optional<Person> optional=list.stream() //Optional是一个容器。java8新出的,防止空指针异常
- .findFirst(); //取第一个
- Person person=optional.get();
- System.out.println(person);
- Optional<Person> optiona2=list.stream()
- .findAny(); //取任何一个
- Person person2=optional.get();
- System.out.println(person2);
- Long ll=list.stream().count(); //个数
- System.out.println(ll);
- Optional<Person> optiona3=list.stream().max((e1,e2)->{ // 取最大值,根据指定比较器
- if(e1.age==e2.age){
- return e1.name.compareTo(e2.name);
- }else{
- return e1.age.compareTo(e2.age);
- }
- });
- System.out.println(optiona3.get());
- Optional<Person> optiona4=list.stream().min((e1,e2)->{ // 取最小值,根据指定比较器
- if(e1.age==e2.age){
- return e1.name.compareTo(e2.name);
- }else{
- return e1.age.compareTo(e2.age);
- }
- });
- System.out.println(optiona4.get());
- }
- }
2、归约
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.*;
- import java.util.function.BinaryOperator;
- import java.util.stream.Collector;
- import java.util.stream.Collectors;
- /**
- * stream
- * 终止操作
- */
- public class TestStream06 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",18),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- tesst01();
- }
- /**
- *reduce()规约 可以将流中元素反复结合起来,得到一个值。返回 T
- */
- public static void tesst01(){
- List<Integer> list1=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
- Integer integer=list1.stream().reduce(0, (x,y)->x+y); //0是起始值。然后0+1+2+3+4+5+...
- System.out.println(integer);
- System.out.println("---------------------------------------------");
- Optional<Integer> optional=list.stream()
- .map(Person::getAge)
- .reduce(Integer::sum);
- System.out.println(optional.get());
- }
- }
3、收集
- package com.bjsxt.stream;
- import com.bjsxt.Person;
- import java.util.*;
- import java.util.function.BinaryOperator;
- import java.util.stream.Collector;
- import java.util.stream.Collectors;
- /**
- * stream
- * 终止操作
- */
- public class TestStream06 {
- public static List<Person> list= Arrays.asList(
- new Person(1,"段然涛",18),
- new Person(2,"李飞宇",34),
- new Person(3,"卢晓倩",25),
- new Person(4,"李小静",67),
- new Person(4,"李小静",18),
- new Person(4,"李小静",67),
- new Person(5,"罗泽成",12)
- );
- public static void main(String[] args){
- tesst02();
- }/**
- * collect(Collector c)方法
- * 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
- * Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。
- * 但是Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例
- */
- public static void tesst02(){
- //收集姓名放入list
- List<String> list2=list.stream()
- .map(Person::getName)
- .collect(Collectors.toList());
- list2.forEach(System.out::println);
- System.out.println("--------------------------------------------");
- //收集姓名放入set
- Set<String> set=list.stream()
- .map(Person::getName)
- .collect(Collectors.toSet());
- set.forEach(System.out::println);
- System.out.println("--------------------------------------------");
- //收集姓名放入指定的集合
- LinkedHashSet<String> linkedHashSet=list.stream()
- .map(Person::getName)
- .collect(Collectors.toCollection(LinkedHashSet::new));
- linkedHashSet.forEach(System.out::println);
- System.out.println("--------------------------------------------");
- //收集总个数
- Long count=list.stream()
- .collect(Collectors.counting());
- System.out.println(count);
- System.out.println("--------------------------------------------");
- //收集平均值
- Double integer=list.stream()
- .collect(Collectors.averagingDouble(Person::getAge));
- System.out.println(integer);
- System.out.println("--------------------------------------------");
- //收集总和
- Integer sum=list.stream()
- .collect(Collectors.summingInt(Person::getAge));
- System.out.println(sum);
- System.out.println("--------------------------------------------");
- //收集最大值
- Optional<Person> optional=list.stream()
- .collect(Collectors.maxBy((p1,p2)->Integer.compare(p1.getAge(),p2.getAge())));
- System.out.println(optional.get());
- System.out.println("--------------------------------------------");
- //收集最小值
- Optional<Person> optional2=list.stream()
- .collect(Collectors.maxBy((p1,p2)->-Integer.compare(p1.getAge(),p2.getAge())));
- System.out.println(optional2.get());
- System.out.println("--------------------------------------------");
- //分组,名字相同的分为一组
- Map<String,List<Person>> map=list.stream()
- .collect(Collectors.groupingBy(Person::getName));
- System.out.println(map);
- System.out.println("--------------------------------------------");
- //分组,名字相同的分为一组,名字相同再根据年龄分组
- Map<String,Map<String,List<Person>>> map1=list.stream()
- .collect(Collectors.groupingBy(Person::getName,Collectors.groupingBy((p)->{
- if(p.getAge()>20){
- return "青年";
- }else{
- return "老年";
- }
- })));
- System.out.println(map1);
- System.out.println("--------------------------------------------");
- //分区,只能分为两个区,true和false两个区,根据年龄40分为两个区
- Map<Boolean,List<Person>> map2=list.stream()
- .collect(Collectors.partitioningBy((e)->e.getAge()>40));
- System.out.println(map2);
- System.out.println("--------------------------------------------");
- //求总和。平均值。总数、最大值、最小值等等
- DoubleSummaryStatistics dss= list.stream()
- .collect(Collectors.summarizingDouble(Person::getAge));
- System.out.println(dss.getSum());
- System.out.println(dss.getAverage());
- System.out.println(dss.getCount());
- System.out.println("--------------------------------------------");
- //把姓名按照“,”分割
- String str=list.stream()
- .map(Person::getName)
- .collect(Collectors.joining(","));
- System.out.println(str);
- System.out.println("--------------------------------------------");
- }
- }
七:并行流和串行流
并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过 parallel() 与sequential() 在并行流与顺序流之间进行切换。java8中的并行流底层就是采用的java的Fork/Join 框架
- package com.bjsxt.forkJoin;
- import java.time.Duration;
- import java.time.Instant;
- import java.util.concurrent.ForkJoinPool;
- import java.util.stream.LongStream;
- /**
- * Created by Administrator on 2019/3/7.
- */
- public class TestForkJoin {
- public static void main(String[] args){
- test02();
- }
- public static void test02(){
- long start = System.currentTimeMillis();
- Long sum = LongStream.rangeClosed(0L, 10000000000L)
- .parallel() //切换到并行流
- .sum();
- System.out.println(sum);
- long end = System.currentTimeMillis();
- System.out.println("耗费的时间为: " + (end - start));
- }
- }
这里有必要简单介绍下Fork/Join框架
Fork/Join 框架:就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行 join 汇总
Fork/Join 框架与传统线程池的区别
采用 “工作窃取”模式(work-stealing):
当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上.在一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态.而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行.那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行.这种方式减少了线程的等待时间,提高了性能
案例:计算start与end之间的值的总和
- package com.bjsxt.forkJoin;
- import java.util.concurrent.RecursiveTask;
- /**
- * 计算start与end之间的值的总和
- */
- public class ForkJoinCalculate extends RecursiveTask<Long> {
- private long start;
- private long end;
- private static final long THRESHOLD = 100000L; //临界值
- public ForkJoinCalculate(long start, long end) {
- this.start = start;
- this.end = end;
- }
- /**
- *
- * @return
- */
- @Override
- protected Long compute() {
- long length=end-start;
- if(length<THRESHOLD){ //已经小于临界值
- long sum=0;
- for(long i=start;i<=end;i++){
- sum+=sum+i;
- }
- return sum;
- }else{ //没到临界值,需要继续分割任务
- long middle=(start+end)/2;
- ForkJoinCalculate left=new ForkJoinCalculate(start,middle);
- left.fork();
- ForkJoinCalculate right=new ForkJoinCalculate(middle+1,end);
- right.fork();
- return left.join()+right.join();
- }
- }
- }
- package com.bjsxt.forkJoin;
- import java.time.Duration;
- import java.time.Instant;
- import java.util.concurrent.ForkJoinPool;
- import java.util.stream.LongStream;
- /**
- * Created by Administrator on 2019/3/7.
- */
- public class TestForkJoin {
- public static void main(String[] args){
- test01();
- }
- public static void test01(){
- Instant strat=Instant.now();
- ForkJoinPool forkJoinPool=new ForkJoinPool();
- ForkJoinCalculate forkJoinCalculate=new ForkJoinCalculate(0,100000000000L);
- long sum=forkJoinPool.invoke(forkJoinCalculate);
- System.out.println(sum);
- Instant end=Instant.now();
- System.out.println("计算耗时:"+ Duration.between(strat,end).toMillis());
- }
- }
八、Optional 类
Optional<T> 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常
- package com.bjsxt.optiona;
- import com.bjsxt.Person;
- import java.util.Optional;
- /**
- * 一、Optional 容器类:用于尽量避免空指针异常
- * Optional.of(T t) : 创建一个 Optional 实例
- * Optional.empty() : 创建一个空的 Optional 实例
- * Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
- * isPresent() : 判断是否包含值
- * orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
- * orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
- * map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
- * flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
- */
- public class TestOptiona {
- public static void main(String[] args){
- test01();
- }
- public static void test01(){
- Optional<Person> optional=Optional.of(new Person()); //如果of()方法里面的值为null,下面一句会发生空指针异常
- Person p=optional.get(); //获取Optional容器中的值
- System.out.println(p);
- }
- public static void test02(){
- Optional<Person> optional=Optional.empty(); //创建一个空的 Optional 实例
- Optional<Person> optiona2=Optional.ofNullable(new Person());//若 参数 不为 null,创建 Optional 实例,否则创建空实例
- }
- public static void test03(){
- Optional<Person> optiona2=Optional.ofNullable(new Person());//若 参数 不为 null,创建 Optional 实例,否则创建空实例
- if(optiona2.isPresent()){ //判断Optional容器中是否包含值
- System.out.println("有值。。。");
- }
- Person p1 = optiona2.orElse(new Person(1,"张三",23)); //如果容器值为空,则值为orElse()方法的参数
- System.out.println(p1);
- Person p2 = optiona2.orElseGet(() -> new Person()); //同orElse(),只不过参数是一个函数式接口
- System.out.println(p2);
- }
- public void test04(){
- Optional<Person> op = Optional.of(new Person(1,"张三",23));
- Optional<String> op2 = op.map(Person::getName);
- System.out.println(op2.get());
- Optional<String> op3 = op.flatMap((e) -> Optional.of(e.getName()));
- System.out.println(op3.get());
- }
- }
9、新的时间与日期API
java之前的时间对象是可变的对象,存在线程安全问题,java8引入了全新的时间类
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。
Instant 时间戳,用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算
Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔
TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。
TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。
java.time.format.DateTimeFormatter 类:该类提供了三种
格式化方法:
预定义的标准格式
语言环境相关的格式
自定义的格式
java8新特性学习2的更多相关文章
- Java8 新特性学习 Lambda表达式 和 Stream 用法案例
Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...
- java8 新特性学习笔记
Java8新特性 学习笔记 1主要内容 Lambda 表达式 函数式接口 方法引用与构造器引用 Stream API 接口中的默认方法与静态方法 新时间日期 API 其他新特性 2 简洁 速度更快 修 ...
- java8新特性学习:函数式接口
本文概要 什么是函数式接口? 如何定义函数式接口? 常用的函数式接口 函数式接口语法注意事项 总结 1. 什么是函数式接口? 函数式接口其实本质上还是一个接口,但是它是一种特殊的接口:SAM类型的接口 ...
- java8新特性学习1
java8增加了不少新特性,下面就一些常见的新特性进行学习... 1.接口中的方法 2.函数式接口 3.Lambda表达式 4.java8内置的四大核心函数式接口 5.方法引用和构造器引用 6.Str ...
- java8新特性学习:stream与lambda
Streams api 对 Stream 的使用就是实现一个 filter-map-reduce 过程,产生一个最终结果,或者导致一个副作用(side effect). 流的操作类型分为两种: Int ...
- Java8 新特性学习
摘自:https://blog.csdn.net/shuaicihai/article/details/72615495 Lambda 表达式 Lambda 是一个匿名函数,我们可以把 Lambda ...
- java8新特性学习笔记(二) 使用流(各种API)
筛选和切片 用谓词筛选,筛选出各个不相同的元素,忽略流中的头几个元素,或将流截断至指定长度 用谓词筛选 Stream接口支持filter方法,该操作接受一个谓词(返回一个boolean的函数) 作为参 ...
- java8新特性学习笔记(二) 流的相关思想
流是什么 流是Java API的新成员,他允许你以声明的方式处理数据集合,就现在来说,可以把他们看成遍历数据集合的高级迭代器.此外,流还可以透明地并行处理,你无须写任何多线程代码. 下面例子是新老AP ...
- Java8新特性学习笔记(一) Lambda表达式
没有用Lambda表达式的写法: Comparator<Transaction> byYear = new Comparator<Transaction>() { @Overr ...
随机推荐
- 检测SQL Server表占用空间大小SQL
检测SQL Server表占用空间大小SQL,要先选择需要查询的数据库,然后点击执行下面脚本. ),ROWS ),reserved ) ,Data ) ,index_size ) ,Unused ) ...
- JavaScript typeof运算符和数据类型
// js有6种数据类型:Undefined.Null.Boolean.String.Number.Object //(01)typeof console.log(typeof undefined); ...
- 使用python简单创建一个用户和商城小程序
整体思路: 1.用户功能:购买.显示余额.列表清单.输入 2.商家功能:修改和添加商品 创建两个接口: 用户: #Author: Gordon #读取文档,生成goodsf = open('goods ...
- Django之(URL)路由系统
路由系统 简而言之,django的路由系统作用就是使views里面处理数据的函数与请求的url建立映射关系.使请求到来之后,根据urls.py里的关系条目,去查找到与请求对应的处理方法,从而返回给客户 ...
- Maven学习篇一:eclipse构建运行maven web项目
1.new->other->maven project->next 2.选择创建简单项目(或者直接去掉勾,在后面选择maven-archetype-webapp) 3.设置坐标,名称 ...
- 【代码笔记】Java基础:Java的方法和类
面向过程与面向对象都是我们编程中,编写程序的一种思维方式.例如:公司打扫卫生(擦玻璃.扫地.拖地.倒垃圾等), 按照面向过程的程序设计方式会思考“打扫卫生我该怎么做,然后一件件的完成”,最后把公司卫生 ...
- github使用手册
1.git init 2.git add README.md (增加文件夹/文件:git add dir/files) 3.git commit -m "注释内容” 4.git push - ...
- 纯css 简单网页
<div id="wrapper"> <header> <section> <h1>Web Design<h1> < ...
- ArcGIS软件操作——地图制图
ArcGIS软件操作系列二(地图制图) 2016年毕业,参加工作,除了平时出差,大部分时间都在使用ArcGIS处理数据.制图,在此,先将一些制图的小心得撰写出来,希望能与各位共同交流. 1 数据准备: ...
- 关于 document.compatMode
今天查资料时无意发现一个以前没有注意到过的属性:document.compatMode 经过一番资料的查询后,了解到以下信息: 我们都知道IE有两种盒子模型,在不声明 !DOCTYPE 时是混杂模式 ...