Java8新特性 Stream的使用

/**
 * 1.Stream关注的是对数据的运算,与CPU打交道
 * 集合关注的是数据的存储,与内存打交道
 * 2.Stream 自己不会存储元素。
 * Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
 * Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
 * 3.一个中间操作链,对数据源的数据进行处理
 * 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
 *
 * @author Manaphy
 * @date 2020/1/28
 */
public class StreamApiTest {
    /**
     * 创建Stream的四种方式
     */
    @Test
    public void test01() {
        //创建Stream方式一:通过集合
        List<Student> list = Student.getList();
        //default Stream<E> stream() : 返回一个顺序流
        Stream<Student> stream = list.stream();
        //default Stream<E> parallelStream() : 返回一个并行流
        Stream<Student> parallelStream = list.parallelStream();

        //创建Stream方式二:通过数组
        int[] arr = new int[]{1, 2, 3, 4, 5, 6};
        //调用Arrays类的static <T> Stream<T> stream(T[] array): 返回一个流
        IntStream intStream = Arrays.stream(arr);
        Student s1 = new Student(1L, "肖战", 15, true);
        Student s2 = new Student(2L, "王一博", 15, true);
        Student[] students = new Student[]{s1, s2};
        Stream<Student> studentStream = Arrays.stream(students);

        //创建Stream方式三:通过Stream的of()
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);

        //创建Stream方式四:创建无限流
        //迭代 public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);//遍历前10个偶数
        //生成 public static<T> Stream<T> generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }

    /**
     * 测试Stream的中间操作
     */
    @Test
    public void test02(){
        //1.筛选与切片
        List<Student> students = Student.getList();
        //filter(Predicate p)——接收 Lambda , 从流中排除某些元素。
        students.stream().filter(student -> student.getAge()>16).forEach(System.out::println);
        //limit(n)——截断流,使其元素不超过给定数量。
        students.stream().limit(2).forEach(System.out::println);
        //skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
        students.stream().skip(3).forEach(System.out::println);
        //distinct()——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
        ArrayList<Student> students1 = new ArrayList<>(students);
        students1.add(new Student(1L,"肖战", 15, true));
        students1.stream().distinct().forEach(System.out::println);

        //2.映射
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        //map(Function f)——接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。
        list.stream().map(String::toUpperCase).forEach(System.out::println);
        students.stream().map(Student::getName).filter(name->name.length()>2).forEach(System.out::println);

        //3.排序
        List<Integer> list2 = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);
        //sorted()——自然排序
        list2.stream().sorted().forEach(System.out::println);
        //sorted(Comparator com)——定制排序
        students.stream().sorted((s1,s2)->Integer.compare(s1.getAge(),s2.getAge())).forEach(System.out::println);
        students.stream().sorted(Comparator.comparingInt(Student::getAge)).forEach(System.out::println);
    }

    /**
     * 测试Stream的终止操作
     */
    @Test
    public void test03(){
        List<Student> students = Student.getList();
        //1.匹配与查找
        //allMatch(Predicate p)——检查是否匹配所有元素。
        boolean allMatch = students.stream().allMatch(student -> student.getAge() > 14);
        if (allMatch){
            System.out.println("所有学生都满15周岁");
        }
        //anyMatch(Predicate p)——检查是否至少匹配一个元素
        boolean anyMatch = students.stream().anyMatch(s -> "肖战".equals(s.getName()));
        if (anyMatch){
            System.out.println("学生中有叫肖战的学生");
        }
        //noneMatch(Predicate p)——检查是否没有匹配的元素。
        boolean noneMatch = students.stream().noneMatch(student1 -> "杨洋".equals(student1.getName()));
        if (noneMatch){
            System.out.println("没有叫杨洋的同学");
        }
        //findFirst——返回第一个元素
        Optional<Student> first = students.stream().findFirst();
        //findAny——返回当前流中的任意元素
        Optional<Student> any = students.stream().findAny();
        //count——返回流中元素的总个数
        long count = students.stream().filter(student -> student.getAge()>15).count();
        //max(Comparator c)——返回流中最大值
        Optional<Integer> max = students.stream().map(Student::getAge).max(Integer::compareTo);
        //min(Comparator c)——返回流中最小值
        Optional<Integer> min = students.stream().map(Student::getAge).min(Integer::compareTo);
        //forEach(Consumer c)——内部迭代
        students.stream().forEach(System.out::println);

        //2.归约
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        //reduce(T identity, BinaryOperator)——可以将流中元素反复结合起来,得到一个值。返回 T
        Integer reduce = list.stream().reduce(0, Integer::sum);
        //reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。返回 Optional<T>
        Optional<Integer> reduce1 = students.stream().map(Student::getAge).reduce(Integer::sum);

        //3.收集
        //collect(Collector c)——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
        //toList 把流中元素收集到List
        List<Student> collect = students.stream().filter(student -> student.getAge() > 15).collect(Collectors.toList());
        //toSet 把流中元素收集到Set
        Set<Student> set = students.stream().filter(student -> student.getAge() > 15).collect(Collectors.toSet());
        //toCollection 把流中元素收集到创建的集合
        ArrayList<Student> arrayList = students.stream().collect(Collectors.toCollection(ArrayList::new));
        //counting 计算流中元素的个数
        long count1 = students.stream().collect(Collectors.counting());
        //summingInt 对流中元素的整数属性求和
        Integer sum = students.stream().collect(Collectors.summingInt(Student::getAge));
        //averagingInt 计算流中元素Integer属性的平均值
        Double avg = students.stream().collect(Collectors.averagingInt(Student::getAge));
        //summarizingInt 收集流中Integer属性的统计值。如:平均值
        IntSummaryStatistics statistics = students.stream().collect(Collectors.summarizingInt(Student::getAge));
        System.out.println(statistics);//IntSummaryStatistics{count=4, sum=65, min=15, average=16.250000, max=18}
        //joining 连接流中每个字符串
        String joining= students.stream().map(Student::getName).collect(Collectors.joining());
        System.out.println(joining);//肖战王一博杨紫李现
        //maxBy 根据比较器选择最大值
        Optional<Student> maxBy = students.stream().collect(Collectors.maxBy(Comparator.comparingInt(Student::getAge)));
        //minBy 根据比较器选择最小值
        Optional<Student> minBy = students.stream().collect(Collectors.minBy(Comparator.comparingInt(Student::getAge)));
        //reducing 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
        int total=students.stream().collect(Collectors.reducing(0, Student::getAge, Integer::sum));
        //collectingAndThen 包裹另一个收集器,对其结果转换函数
        int collectingAndThen= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
        //groupingBy 根据某属性值对流分组,属性为K结果为V
        Map<Integer, List<Student>> groupingBy = students.stream().collect(Collectors.groupingBy(Student::getAge));
        //partitioningBy 根据true或false进行分区
        Map<Boolean, List<Student>> partitioningBy = students.stream().collect(Collectors.partitioningBy(Student::getIsMale));
        System.out.println(partitioningBy);
    }
}

/**
 * Stream的测试类
 *
 * @author Manaphy chen
 * @date 2020/1/22 16:28
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private Long id;

    private String name;

    private int age;

    private Boolean isMale;

    public static List<Student> getList() {
        Student s1 = new Student(1L, "肖战", 15, true);
        Student s2 = new Student(2L, "王一博", 15, true);
        Student s3 = new Student(3L, "杨紫", 17, false);
        Student s4 = new Student(4L, "李现", 18, true);
        return new ArrayList<Student>() {{
            add(s1);
            add(s2);
            add(s3);
            add(s4);
        }};
    }
}
发布了25 篇原创文章 · 获赞 1 · 访问量 1978

猜你喜欢

转载自blog.csdn.net/weixin_45631876/article/details/104372485