StreamAPI

public class StreamTest {

    List<Student> students = Arrays.asList(
            new Student("张三",12, Student.Status.VOCATION),
            new Student("李四",18, Student.Status.BUSY),
            new Student("王五",19, Student.Status.FREE),
            new Student("赵六",39, Student.Status.BUSY)
    );


    /**
     * 1. 创建Stream
     */
    @Test
    public void test(){
        //1. 通过Collection 集合提供的 stream() 或 parallelStream()
        List<String> list = new ArrayList<>();

        Stream<String> stream = list.stream();
        Stream<String> stream1 = list.parallelStream();

        //2.通过Arrays中的静态方法 stream() 获取数组流
        Student[] students = new Student[10];
        Stream<Student> stream2 = Arrays.stream(students);

        //3. 通过Stream的静态方法 of()
        Stream<String> stream3 = Stream.of("aa", "bb", "cc");

        //4. 创建无限流
        //4.1 迭代
        Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
        stream4.limit(4).forEach(System.out::println);

        //4.2 生成
        Stream.generate(()-> (int) (Math.random() * 10))
                .limit(5)
                .forEach(System.out::println);

    }



    /**
     * 2. stream中间操作
     *
     * 筛选与切片
     * filter - 接收Lambda,从流中排除某些元素
     * limit - 截断流,使其元素不超过给定数量
     * skip(n) - 跳过元素,返回一个扔掉了前n 个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
     * distinct - 筛选,通过流所生成元素的 hashCode() 和equals() 去除重复元素。
     *
     *
     * 内部迭代:迭代操作是由Stream API 自己完成的。
     */
    @Test
    public void test1(){
        Stream<Student> stream = students.stream()
                .filter((e) -> {
                    return e.getAge() > 18;
                });

        // 终止操作  直到有终止操作,中间操作才会执行(惰性求值)。
        stream.forEach(System.out::println);
    }

    /**
     * 映射
     * map - 接收lambda, 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
     * flatMap - 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流都连接成一个流。
     */
    @Test
    public void test2(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
        list.stream()
                .map(String::toUpperCase)
                .forEach(System.out::println);


        // 将多stream合并成一个Stream  类似于 addAll(Collection c)
        list.stream()
                .flatMap(StreamTest::filterCharacter)
                .forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        for (char c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }


    /**
     * 排序
     * sorted() - 自然排序(Comparable)
     * sorted(Compartor com) - 定制排序
     */
    @Test
    public void test3(){
        List<String> list = Arrays.asList("ccc", "bbb", "aaa", "ddd", "eee");

        //sorted()
        list.stream()
                .sorted()
                .forEach(System.out::println);

        //sorted(Compartor com)
        students.stream()
                .sorted((s1,s2) ->{
                    if (s1.getAge() > s2.getAge()){
                        return -1;
                    }else if (s1.getAge() < s2.getAge()){
                        return 1;
                    }else {
                        return s1.getName().compareTo(s2.getName());
                    }
        }).forEach(System.out::println);

    }

    /**
     * 3. 终止操作
     *
     * 查找与匹配
     * allMatch - 检查是否匹配所有元素
     * anyMatch - 检查是否至少匹配一个元素
     * noneMatch - 检查是否没有匹配所有元素
     * findFirst - 返回第一个元素
     * findAny - 返回当前流中的任意元素
     * count - 返回流中元素的总个数
     * max - 返回流中的最大值
     * min - 返回流中的最小值
     */
    @Test
    public void test4(){
        // allMatch
        boolean b1 = students.stream()
                .allMatch((x) -> x.getStatus().equals(Student.Status.BUSY));
        System.out.println(b1);  //false


        //anyMatch
        boolean b2 = students.stream()
                .anyMatch((x) -> x.getStatus().equals(Student.Status.BUSY));
        System.out.println(b2); //true

        //noneMatch
        boolean b3 = students.stream()
                .noneMatch((x) -> x.getStatus().equals(Student.Status.BUSY));
        System.out.println(b3); //false

        //findFirst
        Student student = students.stream()
                .findFirst().get();
        System.out.println(student);

        //findAny
        Student student1 = students.stream()
                .findAny().get();
        System.out.println(student1);

        //count
        long count = students.stream().count();
        System.out.println(count);

        //max
        Student student2 = students.stream()
                .max(Comparator.comparingInt(Student::getAge))
                .get();
        System.out.println(student2);

        //min
        Integer minAge = students.stream()
                .map(Student::getAge)
                .min(Integer::compare).get();
        System.out.println(minAge);
    }


    /**
     * 归约
     *
     * reduce(T identity, BinaryOperator)
     *
     * reduce(BinaryOperator)
     * 可以将流中元素反复结合起来,得到一个值。
     */
    @Test
    public void test5(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);


        Integer s = list.stream()
                .reduce(100, Integer::sum);
        System.out.println(s);  //145

        Integer s1 = list.stream()
                .reduce(Integer::sum).get();
        System.out.println(s1); //45

        Optional<Integer> reduce = students.stream()
                .map(Student::getAge)
                .reduce(Integer::sum);
        System.out.println(reduce.get());
    }


    /**
     * 收集
     * collect - 将流转换为其它形式。
     * 接收一个Collector接口的实现,用于给Stream中元素做汇总方法。
     */
    @Test
    public void  test6(){
        //收集成Collection集合类

        List<String> list = students.stream()
                .map(Student::getName)
                .collect(Collectors.toList());


        Set<String> set = students.stream()
                .map(Student::getName)
                .collect(Collectors.toSet());

        HashSet<String> hashSet = students.stream()
                .map(Student::getName)
                .collect(Collectors.toCollection(HashSet::new));

        Map<String, Student> map = students.stream()
                .collect(Collectors.toMap(Student::getName, (s) -> s));

    }

    /**
     * 求值
     */
    @Test
    public void test7(){
        // 总数
        Long collect = students.stream()
                .collect(Collectors.counting());
        System.out.println(collect);

        // 总和
        Integer sum = students.stream()
                .collect(Collectors.summingInt(Student::getAge));
        System.out.println(sum);


        // 平均值
        Double avg = students.stream()
                .collect(Collectors.averagingInt(Student::getAge));
        System.out.println(avg);

        // 最大值
        Optional<Student> max = students.stream()
                .collect(Collectors.maxBy((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge())));
        System.out.println(max.get());

        // 最小值
        Optional<Integer> min = students.stream()
                .map(Student::getAge)
                .collect(Collectors.minBy(Integer::compareTo));
        System.out.println(min.get());


        //总的 求值收集器
        IntSummaryStatistics statistics = students.stream()
                .collect(Collectors.summarizingInt(Student::getAge));
        System.out.println(statistics.getCount());
        System.out.println(statistics.getSum());
        System.out.println(statistics.getAverage());
        System.out.println(statistics.getMax());
        System.out.println(statistics.getMin());
    }


    /**
     * 分组
     */
    @Test
    public void test8(){

        // 按照Status分组
        Map<Student.Status, List<Student>> map = students.stream()
                .collect(Collectors.groupingBy(Student::getStatus));
        System.out.println(map);

        // 多级分组
        Map<Student.Status, Map<String, List<Student>>> map1 = students.stream()
                .collect(Collectors.groupingBy(Student::getStatus, Collectors.groupingBy((s) -> {
                    if (s.getAge() < 18) {
                        return "少年";
                    } else if (s.getAge() >= 18 && s.getAge() < 20) {
                        return "成年";
                    } else {
                        return "老年";
                    }
                })));
        System.out.println(map1);

    }

    /**
     * 分区
     */
    @Test
    public void test9(){
        Map<Boolean, List<Student>> map = students.stream()
                .collect(Collectors.partitioningBy((s) -> s.getStatus() == Student.Status.BUSY));
        System.out.println(map);
    }

    /**
     * join 连接字符串
     */
    @Test
    public void test10(){
        String joinStr = students.stream()
                .map(Student::getName)
                .collect(Collectors.joining(","));
        System.out.println(joinStr); //张三,李四,王五,赵六
    }

}

Lambda 方法引用与构造器引用

//方法引用
public class TestMethodRef {

    /**
     * 若lambda实现体内调用方法的 参数 与返回值 与 函数式接口一样   那么就可以使用 `方法引用`
     *
     * 1. 对象::实例方法名
     *
     * 2. 类::静态方法名
     */

    //对象::实例方法名
    @Test
    public void test(){
        // 空参数 返回值T
        Student student = new Student();
        Supplier<String> su = student::getName;

        // Runnable接口 空参数 空返回值
        new Thread(student::haha).start();
    }

    // 类::静态方法名
    @Test
    public void test2(){

        //原来的写法
        Comparator<Integer> com =  (x,y)-> Integer.compare(x,y);

        //改变后的写法
        Comparator<Integer> com1 = Integer::compare;
    }


    /**
     *  若函数式接口的
     *          第一个参数 是lambda体 实例方法 的调用者
     *          第二个参数 是lambda体 实例方法 的参数
     *      那么可以使用 类::实例方法名
     */
    @Test
    public void test3(){
        // 原来的写法
        BiPredicate<String,String> bp = (x,y) -> x.equals(y);

        // 改变后的写法
        BiPredicate<String,String> bp1 = String::equals;
    }
}
/**
 * 构造器引用
 *
 *  格式: ClassName::new
 */
public class TestConstructRef {

    @Test
    public void  test(){

        //原来写法
        Supplier<Student> stu = ()-> new Student();

        //构造器引用写法  使用的是空参构造  实际上与Supplier的 get()方法 的参数与返回值一致
        Supplier<Student> stu1 = Student::new;

    }
}
万般皆下品,唯有读书高!
原文地址:https://www.cnblogs.com/s686zhou/p/15241923.html