Jdk8新特性之Stream(2)

Stream流中的结果到集合中
Stream流提供 collect 方法,其参数需要一个 java.util.stream.Collector<T,A, R> 接口对象来指定收集到哪
种集合中。java.util.stream.Collectors 类提供一些方法,可以作为 Collector`接口的实例:

public static <T> Collector<T, ?, List<T>> toList() :转换为 List 集合。
public static <T> Collector<T, ?, Set<T>> toSet() :转换为 Set 集合。

下面是这两个方法的基本使用代码:

// 将流中数据收集到集合中
    @Test
    public void testStreamToCollection() {
        Stream<String> stream = Stream.of("aa", "bb", "cc");
        ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
        HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
    }

Stream流中的结果到数组中
Stream提供 toArray 方法来将结果放到一个数组中,返回值类型是Object[]的:

@Test
    public void testStreamToArray() {
        Stream<String> stream = Stream.of("aa", "bb", "cc");
        String[] strings = stream.toArray(String[]::new);
        for (String str : strings) {
            System.out.println(str);
        }
    }

对流中数据进行聚合计算

当我们使用 Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小
值,求总和,平均值,统计数量。

 @Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 88),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 77));
       //1. 最大值
        Optional<Student> collect = studentStream.collect(Collectors.maxBy(Comparator.comparing(Student::getSocre)));
        //studentStream.collect(Collectors.maxBy((o1,o2) ->( o1.getSocre() - o2.getSocre())));
        System.out.println(collect.get());  //Student{name='迪丽热巴', age=56, socre=99}

    }
  @Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 88),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 77));
       //最小值
        Optional<Student> collect = studentStream.collect(Collectors.minBy(Comparator.comparing(Student::getSocre)));
        //studentStream.collect(Collectors.minBy((o1,o2) ->( o1.getSocre() - o2.getSocre())));
        System.out.println(collect.get());  //Student{name='柳岩', age=52, socre=77}

    }
 @Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 88),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 77));
       // studentStream.map(Student::getSocre).reduce(Integer::sum);
        Integer collect = studentStream.collect(Collectors.summingInt(Student::getSocre));
        System.out.println(collect);
    }
 @Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 88),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 77));
        Double collect = studentStream.collect(Collectors.averagingDouble(Student::getSocre));
        System.out.println(collect);
    }

对流中数据进行分组
当我们使用Stream流处理数据后,可以根据某个属性将数据分组:

  @Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 88),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 77));
        Map<Integer, List<Student>> collect = studentStream.collect(Collectors.groupingBy(Student::getAge));
        collect.forEach( (k,v) -> {
            System.out.println(k + "::" + v);
        });
    }

@Test
   public void test(){
       Stream<Student> studentStream = Stream.of(
               new Student("赵丽颖", 58, 95),
               new Student("杨颖", 56, 58),
               new Student("迪丽热巴", 56, 99),
               new Student("柳岩", 52, 47));
        Map<String, List<Student>> collect = studentStream.collect(Collectors.groupingBy(s -> s.getSocre() > 60 ? "及格" : "不及格"));
        collect.forEach( (k,v) -> {
            System.out.println(k + "::" + v);
        });
    }

对流中数据进行多级分组

@Test
   public void test(){
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
        Map<Integer, Map<String, List<Student>>> map =
                studentStream.collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(s -> {
                    if (s.getSocre() >= 90) {
                        return "优秀";
                    } else if (s.getSocre() >= 80 && s.getSocre() < 90) {
                        return "良好";
                    } else if (s.getSocre() >= 80 && s.getSocre() < 80) {
                        return "及格";
                    } else {
                        return "不及格";
                    }
                })));

        map.forEach((k, v) -> {
            System.out.println(k + " == " + v);
        });
    }

对流中数据进行分区
Collectors.partitioningBy 会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。

 @Test
   public void test(){
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
// partitioningBy会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。
        Map<Boolean, List<Student>> map = studentStream.collect(Collectors.partitioningBy(s ->
                s.getSocre() > 90));
        map.forEach((k, v) -> {
            System.out.println(k + " == " + v);
        });
    }

对流中数据进行拼接
Collectors.joining 会根据指定的连接符,将所有元素连接成一个字符串。

 @Test
   public void test(){
        Stream<Student> studentStream = Stream.of(
                new Student("赵丽颖", 52, 95),
                new Student("杨颖", 56, 88),
                new Student("迪丽热巴", 56, 99),
                new Student("柳岩", 52, 77));
        String collect = studentStream
                .map(Student::getName)
                .collect(Collectors.joining(">_<", "^_^", "^v^"));
        System.out.println(collect);
    }

 /**
     * 测试flatMap
     */
    @Test public void testFlatMap() {
        List<String> strs = Arrays.asList("孙悟空", "猪八戒");
        String collect = strs.stream()
                .map(s -> {
                    char[] arr01 = s.toCharArray();
                    Character[] arr02 = new Character[arr01.length];
                    for (int i = 0; i < arr02.length; i++) {
                        arr02[i] = arr01[i];
                    }
                    return arr02;
                })
                .flatMap(Arrays::stream)   // 扁平化
                .map(String::valueOf)
                .collect(Collectors.joining(","));
        System.out.println(collect); // 孙,悟,空,猪,八,戒
    }
 /**
     * SQL与Stream
     * 
     */
    @Test public void testStreamCompSql() {
        // select name, max(age) from person where name in ('孙悟空','猪八戒') and age is not null group by name order by name
        LinkedHashMap<String, Optional<Integer>> map = 
            plist.stream()
                 .filter(p -> Arrays.asList("孙悟空","猪八戒").contains(p.getName())) // name in ('孙悟空','猪八戒')
                 .filter(p -> nonNull(p.getAge()))                                  // age is not null
                 .sorted(comparing(Person::getName,nullsLast(naturalOrder())))      // order by name, 注意空值问题
               //.collect(groupingBy(Person::getName)                               // Map<String, List<Person>>, 此处搜集到的还是人,但需要的是年龄,继续downstream搜集
                 .collect(groupingBy(Person::getName,LinkedHashMap::new,mapping(Person::getAge, maxBy(Integer::compare))))   // group by name
                 ;
        System.out.println(map);         // {孙悟空=Optional[18], 猪八戒=Optional[28]}
             
        // select * from person where age = (select max(age) from person) limit 1    
        Optional<Person> first = plist.stream().sorted((p1,p2) -> p2.getAge() - p1.getAge()).findFirst();    
        System.out.println(first.get()); // Person [name=沙悟净, age=48, salary=40000.0]
    }
posted @ 2020-03-27 00:50  天宇轩-王  阅读(280)  评论(0编辑  收藏  举报