java8中的steam流

简介: java8中的steam流

1,创建stream流

//1,通过Collection系列集合提供的stream方法
        List<String> list = new ArrayList<String>();
        Stream<String> stream1 = list.stream();
        //2,通过Arrays中提供的静态方法stream 获取数组流
        String[] strs = new String[10];
        Stream<String> stream2 = Arrays.stream(strs);
        //3,通过Stream类中的静态方法 of
        Stream<String> stream3 = Stream.of("c", "s", "s");
        //4,创建无限流
          //迭代  iterate参数 (从 0 开始 ,每次+2)
        Stream<Integer> stream4_1 = Stream.iterate(0, x -> x + 2);
        stream4_1.forEach(System.out::println);
          //生成  参数使用的是供给型接口,无参,有返回值 下面是返回了一个随机double类型的数值

       Stream.generate(() -> Math.random()).forEach(System.out::println);


2,操作流

stream流的操作分为中间操作和终止操作,下面这个操作是从流中过滤大于3的内容


1,filter   接受Lambda,从流中排除某些元素


List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
        //中间操作:不会执行任何操作
        Stream<Integer> stream = list.stream()
                .filter(e -> {
                    System.out.println("过滤 中间操作");
                    return e>3;
                });
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);

如果不执行终止操作,中间操作是不会执行的


多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!

而在终止操作时一次性全部处理,称为“惰性求值”。


2,limit(n)  截断流,使其元素不超过给定数量


List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
        //中间操作:不会执行任何操作
        Stream<Integer> stream = list.stream()
                .filter(e -> {
                    System.out.println("过滤 中间操作");
                    return e>3;
                })
                .limit(2);
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);

输出结果就是  4  5


3,skip(n)  跳过元素,返回一个扔掉了前n个元素的流,如果流中元素不足n个,则返回一个空流。与limit互补

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
        //中间操作:不会执行任何操作
        Stream<Integer> stream = list.stream()
                .skip(5);
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);

输出结果就是 6 7 8


4,去重操作 distinct


List<Integer> list = Arrays.asList(1,2,3,4,4,4);
        //中间操作:不会执行任何操作
        Stream<Integer> stream = list.stream()
                .distinct();
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);

输出结果 1 2 3 4


这里去重是根据对象的hasCode和equals方法,所以如果要对实体类对象执行去重操作,需要重写这两个方法。


5,映射


map 接收Lambda ,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素,上,并将其映射成一个新的元素。


全部转换为大写

List<String> list = Arrays.asList("a","vvv","ddd");
        //中间操作:不会执行任何操作
        Stream<String> stream = list.stream()
                .map(x -> x.toUpperCase());
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);
末尾加s
        List<String> list = Arrays.asList("a","vvv","ddd");
        //中间操作:不会执行任何操作
        Stream<String> stream = list.stream()
                .map(x -> x+"s");
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);

flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流


接受一个返回值是Stream的方法,把每次返回的流中的数据整合到一个流中。


6,排序


sorted 自然排序 按对象执行的方式进行排序,


       List<String> list1 = Arrays.asList("a","vvv","ddd");

       //中间操作:不会执行任何操作

       Stream<String> stream = list1.stream()

               .sorted();

       //终止操作:一次性执行全部内容,惰性求值

       stream.forEach(System.out::println);

输出结果 a ddd vvv



定制排序 sorted(Comparator c)


这里有个Person类,

public class Person {
    private Integer age;
    private double salary;
    public Person() {
    }
    public Person(Integer age, double salary) {
        this.age = age;
        this.salary = salary;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", salary=" + salary +
                '}';
    }
}


按年龄排序,如果年龄相同,按工资排序


List<Person> list = Arrays.asList(
                new Person(18,3939),
                new Person(38,9999),
                new Person(19,9988),
                new Person(38,99)
        );
        //如果只按一个年龄属性排序
        list.stream().sorted(Comparator.comparing(Person::getAge));
        //按多个字段排序
        Stream<Person> stream = list.stream()
                .sorted((x,y) -> {
                    if(x.getAge() == y.getAge()){
                        return x.getSalary() > y.getSalary()? 1:-1;
                    }
                    return x.getAge().compareTo(y.getAge());
                });
        //终止操作:一次性执行全部内容,惰性求值
        stream.forEach(System.out::println);


3,终止操作

查找与匹配

List<Person> list = Arrays.asList(
                new Person(18,3939),
                new Person(38,9999),
                new Person(17,9999),
                new Person(19,9988),
                new Person(38,99)
        );
        //是否匹配所有元素 此处返回false
        boolean b = list.stream().allMatch(e -> e.getAge() == 18);
        System.out.println(b);
        //至少匹配一个元素,此处返回true
        boolean b1 = list.stream().anyMatch(e -> e.getAge() == 19);
        System.out.println(b1);
        //流中是否没有匹配元素,此处返回false
        boolean b2 = list.stream().noneMatch(e -> e.getAge() == 19);
        System.out.println(b2);
        //排序后获取第一个元素
        Optional<Person> first = list.stream().sorted((x, y) -> x.getAge().compareTo(y.getAge())).findFirst();
        System.out.println(first);
        //获取流中任意一个元素
        list.stream().findAny();
        //返回流中元素的总个数
        list.stream().count();
        //返回流中最大值 此处根据年龄比较
        Optional<Person> max = list.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));
        System.out.println(max.get());
        //返回流中最小值 此处根据年龄比较
        Optional<Person> min = list.stream().min((x, y) -> x.getAge().compareTo(y.getAge()));
        System.out.println(min.get());
        //获取最小的年龄
        Optional<Integer> age = list.stream().map(Person::getAge).min(Integer::compareTo);
        System.out.println(age.get());
        //获取一个并行流,并行流会使用多个线程操作流,stream()获取的是串行流,单个线程操作流
        list.parallelStream();


归约:

List<Integer> intList = Arrays.asList(
          1,2,3,4,5,6,7,8,9,10
        );
        /**
         * 第一个参数是从几开始,第二个参数是执行的操作
         * x=0,y=1 x+y=1
         * x=1,y=2 x+y=3
         * x=3,y=3 x+y=6
         * x=6,y=4 x+y=10
         * x=10,y=5 x+y=15
         * x=15,y=6 x+y=21
         * x=21,y=7 x+y=28
         * x=28,y=8 x+y=36
         * x=36,y=9 x+y=45
         * x=45,y=10 x+y=55
         * 输出结果为55
         */
        Integer reduce = intList.stream().reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        List<Person> list = Arrays.asList(
                new Person(18,3939),
                new Person(38,9999),
                new Person(17,9999),
                new Person(19,9988),
                new Person(38,99)
        );
        //取出所有年龄,然后相加
        Optional<Integer> reduce1 = list.stream().map(Person::getAge).reduce(Integer::sum);
        System.out.println(reduce1.get());


收集:


//取出所有年龄放到list集合中
        List<Integer> toList = list.stream().map(Person::getAge)
                .collect(Collectors.toList());
        //取出所有年龄放到set集合中
        Set<Integer> toSet = list.stream().map(Person::getAge)
                .collect(Collectors.toSet());
        //取出所有年龄放到hashSet集合中
        HashSet<Integer> toHashSet = list.stream().map(Person::getAge)
                .collect(Collectors.toCollection(HashSet::new));
        //获取集合中元素总和
        Long count = list.stream().collect(Collectors.counting());
        //获取年龄平均值
        Double avg = list.stream().collect(Collectors.averagingInt(Person::getAge));
        //获取工资总和
        Double sum = list.stream().collect(Collectors.summingDouble(Person::getSalary));
        //获取工资最大值的人
        Optional<Person> max = list.stream().collect(Collectors.maxBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary())));
        System.out.println(max.get());
        //获取工资最小值的人
        Optional<Person> min = list.stream().collect(Collectors.minBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary())));
        System.out.println(min.get());
        //获取元素个数、总和、最小值、平均值、最大值
        DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Person::getSalary));
        System.out.println(collect);
        //输出结果:DoubleSummaryStatistics{count=5, sum=34024.000000, min=99.000000, average=6804.800000, max=9999.000000}


分组和分区

//按年龄分组,年龄相同的是一组
        Map<Integer, List<Person>> 分组 = list.stream().collect(Collectors.groupingBy(Person::getAge));
        //按年龄分组后按工资分组,多级分组
        Map<Integer, Map<String, List<Person>>> 多级分组 = list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(x -> {
            return x.getSalary() > 3000 ? "高" : "低";
        })));
        //分区 满足条件的一个区,不满足条件的一个区
        Map<Boolean, List<Person>> collect1 = list.stream().collect(Collectors.partitioningBy(e -> e.getSalary() < 2000));

连接


List<String> strs = Arrays.asList("a","b","cd");
        //连接所有内容
        String str = strs.stream().collect(Collectors.joining());
        System.out.println(str);
        //输出:abcd
        //连接所有内容,中间加一个逗号隔开
        String str1 = strs.stream().collect(Collectors.joining(","));
        System.out.println(str1);
        //输出:a,b,cd
        //连接所有内容,中间加一个逗号隔开,两边加上括号
        String str2 = strs.stream().collect(Collectors.joining(",","(",")"));
        System.out.println(str2);
        //输出:(a,b,cd)


相关文章
|
2月前
|
Java 大数据 API
别死脑筋,赶紧学起来!Java之Steam() API 常用方法使用,让开发简单起来!
分享Java Stream API的常用方法,让开发更简单。涵盖filter、map、sorted等操作,提高代码效率与可读性。关注公众号,了解更多技术内容。
|
存储 SQL 分布式计算
一文详解 Java Steam
本次主要介绍Stream引入原因、相关概念以及常用操作
1125 0
|
Java
Java steam 中排序的用法
排序的用法
1102 0
|
存储 SQL 安全
【杭州研发中心-后端二团队】Java8新特性之Lambda表达式和Steam流
【杭州研发中心-后端二团队】Java8新特性之Lambda表达式和Steam流
|
20天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
11天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
6天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
11天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
42 1
|
19天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
40 6
|
19天前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####