Java Stream流
Function.identity()获取原流中的值
创建流
Collection.stream() / Collection.parallelStream():从集合生成流,后者为并行流。
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
Arrays.stream(T[] array):从数组生成流。
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
IntStream.range(int startInclusive, int endExclusive):生成一个包含从startInclusive到endExclusive(不包括)的整数序列的流。
Stream.of(T… values):从给定值创建流。
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
stream2.forEach(System.out::println); // 0 2 4 6 8 10
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::println);
中间操作
map
对流中的每个元素应用一个函数,并将该函数应用的结果作为新的流返回。这个过程是转换性的,意味着它会产生一个新的流,其中的元素是原始元素经过转换后的结果。(对流中每个元素进行函数处理,并返回一个处理后的新流)
  List<Integer> squares = numbers.stream()
                                .map(n -> n * n)
                                .collect(Collectors.toList());
flatMap
对流中的每个元素应用一个函数,这个函数会将每个元素转换为另一个流,然后将所有这些流连接成一个单一的流。()
MapTOxxx
单独流中某属性创建一个新的流用以接收(常用于从对象的流中捕获指定属性)
filter 过滤
filter:用于对Stream流中的数据进行过滤
 filter(Predicate<? super T>predicate)
 filter方法的参数Predicate是一个函数式接口,可以使用lambda表达式
 Predicate中的抽象方法
 boolean test(T t)
List<User> user1 = new ArrayList<>();
        // 基础
        for (User user : users) {
            if (user.getId()%2==0){
                user1.add(user);
            }
        }
        //1:lambda
        List<User> user2 = users.stream().filter((user)->user.getId()%2==0).collect(Collectors.toList());
        //2: 匿名内部类 重写 Predicate#test
        List<User> user3 = users.stream().filter(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return user.getId()%2==0;
            }
        }).collect(Collectors.toList());
        //3: 方法引用 需要在 User类中 新增boolean isEven(User user) 方法
        //List<User> user4 = users.stream().filter(User::isEven).collect(Collectors.toList());
distinct 去重
list1.stream().distinct().collect(Collectors.toList());
注:对于基本数据类型通过 == 判定值是否相同。引用数据类型通过其 equals() 方法判定。
limit 截取
limit:用于截取流中的元素
 limit可以对流进行截取,只取用前n个
 limit(long maxSize); [0,maxSize)
 参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作
 limit是一个延迟方法,可以继续使用Stream流方法
list1.stream().limit(2).collect(Collectors.toList());
skip 跳过
skip :用于截取流中的元素
 skip 可以对流进行截取,只取用前n个
 skip (long minSize); [minSize,-1]
 参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作
list1.stream().skip(2).collect(Collectors.toList());
sorted 排序
sorted 对流中的内容进行排序
 对于基本数据类型直接比较排序
 对于对象则需要对象实现对应的 compareTo 接口才能直接调用比较方法
list.stream().sorted().collect(Collectors.toList()); // 默认升序     
list.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList());// 根据返回值判定 正-升,0-等,负-降
list.stream().sorted(new Comparator<Integer>() {
     @Override
      public int compare(Integer o1, Integer o2) {
          return o1 - o2;
      }
}).collect(Collectors.toList());
//对于实体类 
users.stream().sorted().collect(Collectors.toList()); //该类必须实现 compareTo 接口
users.stream().sorted(Comparator.comparing(User::getId)).collect(Collectors.toList());
users.stream().sorted((o1, o2) -> o1.getAccount().compareTo(o2.getAccount())).collect(Collectors.toList());
users.stream().sorted(new Comparator<User>() {
   @Override
   public int compare(User o1, User o2) {
       return o1.getId().compareTo(o2.getId());
   }
}).collect(Collectors.toList());
reduce统计
users.stream().map(User::getId).collect(Collectors.toList());
users.stream().map(user -> user.getId()).reduce((o1, o2) -> o1+o2);
终止操作
forEach遍历
users.stream().forEach();
list 转 list
最终结果或流内容提取
list.stream().map(User::getId).collect(Collectors.toList());```
List 转 Map
从流内容中获取关注部分
Map<Long, User> collect = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
anyMatch 短路匹配 boolean
匹配到一个就返回 true
users.stream().anyMatch(user -> user.getName().length()==3)
allMatch 全部匹配 boolean
所有的都要满足条件才返回true
sers.stream().allMatch(user->user.getId()>1)
noneMatch 全部不匹配boolean
所有的都不满足条件才返回true
sers.stream().noneMatch(user->user.getId()>1)
findAny/findFirst 查找 obj
  //随机获取流中的一个元素,串行流为第一个,并行流可能随机
  Optional<User> any = users.stream().findAny();
  User user1 = any.get();
  //ifPresent 如果存在则执行
  users.stream().findAny().ifPresent(user -> System.out.println(user));
  //findFirst 不论串行、并行都获取第一个
  users.stream().findFirst().ifPresent(user -> System.out.println(user));
收集齐中joining() 方法 string
list.stream().map(String::valueOf).collect(Collectors.joining("-"));
users.stream().map(user -> user.getName()).collect(Collectors.joining("-"));
0-1-2-3-4-5-6-7-8-9
岇鶯翰-逼隗埈蝠-飇冼剉-丟诈乴喪-餢鞋損-辶陀膗葷-铚鈭膕-痷鰎墕熢-釅烸麉-搂軄汿榿
分组 Collectors.groupingBy()
items.stream().collect(Collectors.groupingBy(Function.identity()));
list.stream().collect(Collectors.groupingBy(User::getSex));
Map<String, Long> result2 = items.stream().collect(
                Collectors.groupingBy(
                        Function.identity(), Collectors.counting()
                )
        );  
最值max,min
从流中获取最大的值
list.stream().max(Comparator.comparing(Integer::intValue)).get();// 9
users.stream().max(Comparator.comparing(User::getId)).get(); // id10
users.stream().min(Comparator.comparing(User::getAccount)).get();  // id9
users.stream().max(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 1
users.stream().min(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 10
注:需要传入一个比较器,因此取到的最大值不一定就是真的最大值,根据你的比较器做的选值(源码如下截图);

average 平均值
顾名思义取平均值常与 mapToInt、mapToDouble 使用










