龙空技术网

Java8新特性Stream的常见用法

希留说it 583

前言:

而今各位老铁们对“c语言stream”大概比较注意,你们都想要了解一些“c语言stream”的相关文章。那么小编同时在网摘上搜集了一些关于“c语言stream””的相关内容,希望我们能喜欢,兄弟们快快来了解一下吧!

Stream简介

Stream流是java 8 中新引入的特性,用来处理集合中的数据,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。

Stream不是数据结构,也不保存数据,它是有关算法和计算的,更像一个高级版本的迭代器Iterator。原始版本的 Iterator,只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“判断是否包含某个字符”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,可以很方便地写出高性能的并发程序。

Stream的使用

流操作的类型有三种:

(1)创建流

(2)修改流元素(中间操作,Intermediate Operations)

(3)消费流元素(终端操作,Terminal Operations)

创建流

流有两种:(1)stream() : 创建串行流。(2)parallelStream() : 创建并行流。

并行流的特点就是将一个大任务切分成多个小任务,无序一起执行,当然如果我们需要顺序输出的话可以使用forEachOrdered,速度会比串行流快一些。它通过默认的ForkJoinPool,可能提高你的多线程任务的速度。

(1) 通过Stream.of()将元素转化成流

Stream.of创建流Stream<String> stream = Stream.of("你", "我", "她");

(2)每个集合都可以通过调用 stream() 方法来产生一个流

//String [] strArray = new String[] {"a", "b", "c"};stream = Stream.of(strArray);stream = Arrays.stream(strArray);// List<String> list = Arrays.asList(strArray);stream = list.stream();//Set<String> w = new HashSet<>(Arrays.asList(strArray))stream = w.stream();

使用举例

案例里使用的类

class Person {        private String name;  // 姓名        private int salary; // 战斗力        private int age; // 年龄        private String sex; //性别        private String area;  // 必杀技        // 构造方法        public Person(String name, int salary, int age,String sex,String area) {            this.name = name;            this.salary = salary;            this.age = age;            this.sex = sex;            this.area = area;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public int getSalary() {            return salary;        }        public void setSalary(int salary) {            this.salary = salary;        }        public int getAge() {            return age;        }        public void setAge(int age) {            this.age = age;        }        public String getSex() {            return sex;        }        public void setSex(String sex) {            this.sex = sex;        }        public String getArea() {            return area;        }        public void setArea(String area) {            this.area = area;        }        @Override        public String toString() {            return "Person{" +                    "name='" + name + '\'' +                    ", salary=" + salary +                    ", age=" + age +                    ", sex='" + sex + '\'' +                    ", area='" + area + '\'' +                    '}';        }    }

(1) 遍历/匹配(foreach/find/match)

Stream也是支持类似集合的遍历和匹配元素的,只是Stream中的元素是以Optional类型存在的。Optional类是一个可以为null的容器对象,调用get()方法会返回该对象。

    @Test    public void streamTest1() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 30, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        // 遍历输出符合条件的对象, 战斗力大于8000        personList.stream().filter(person -> person.getSalary() > 8000).forEach(System.out::println);        // 匹配第一个        Optional<Person> findFirst = personList.stream().filter(person -> person.getAge() > 18).findFirst();        System.out.println("匹配第一个值:" + findFirst.get());        // 匹配随机一个(适用于并行流)        Optional<Person> findAny = personList.parallelStream().filter(person -> person.getAge() > 18).findAny();        System.out.println("匹配随机一个值:" + findAny.get());        // 是否包含符合特定条件  年龄大于20        boolean anyMatch = personList.stream().anyMatch(person -> person.getAge() > 20);        System.out.println("是否存在年龄大于20的:" + anyMatch);    }

运行结果:

(2)筛选(filter)

筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。

 @Test    public void streamTest2() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 30, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        //筛选出所有战斗力大于8000的        List<Person> list =  personList.stream().filter(person -> person.getSalary() > 8000).collect(Collectors.toList());        System.out.println("战斗力大于8000的值:" + list);    }

运行结果:

(3)聚合(max/min/count/sum)

max、min、count、sum这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。

    @Test    public void streamTest3() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        //获取年龄最大的        Optional<Person> max = personList.stream().max(Comparator.comparing(Person::getAge));        System.out.println("年龄最大的是:" + max.get());        //获取战斗力最小的        Optional<Person> min = personList.stream().min(Comparator.comparing(Person::getSalary));        System.out.println("战斗力最小的是:" + min.get());        //计算战斗力大于8000的有几个人        long count = personList.stream().filter(person -> person.getSalary() > 8000).count();        System.out.println("战斗力大于8000的人数是:" + count);        //计算总年龄是多少        int sum = personList.stream().mapToInt(person -> person.getAge()).sum();        System.out.println("总年龄是是:" + sum);    }

运行结果:

(4)排序(sorted)

stream中有两种排序:

sorted():自然排序,流中元素需实现Comparable接口

sorted(Comparator com):自定义排序,自定义Comparator排序器

    @Test    public void streamTest4() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        //按战斗力升序排序(自然排序)        List<Person> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).collect(Collectors.toList());        System.out.println("按战斗力升序排序:" + newList);        //按战斗力降序排序(自然排序)        List<Person> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).collect(Collectors.toList());        System.out.println("按战斗力降序排序:" + newList2);        // 先按年龄再按战斗力排序(自定义排序 降序)        List<Person> newList3 = personList.stream().sorted((p1, p2) -> {            if (p1.getAge() == p2.getAge()) {                return p2.getSalary() - p1.getSalary();            } else {                return p2.getAge() - p1.getAge();            }        }).collect(Collectors.toList());        System.out.println("先按年龄再按战斗力:" + newList3);    }

运行结果:

(5) 映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

    @Test    public void streamTest5() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        //将人物和必杀技组合,        List<String> strList = personList.stream().map(person -> person.getName() + "-->" + person.getArea()).collect(Collectors.toList());        System.out.println("人物和必杀技组合:" + strList);            }

运行结果:

(6)归约(reduce)

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

    @Test    public void streamTest6() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1","螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1","须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2","治疗术"));        personList.add(new Person("自来也", 8200, 30, "1","通灵术"));        personList.add(new Person("大蛇丸", 9500, 31, "1","八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2","百豪之术"));        //求战斗力总和 方式1        Integer sum = personList.stream().map(Person::getSalary).reduce((x,y) -> x + y).get();        System.out.println("战斗力总和(方式1):" + sum);        //求战斗力总和 方式2        Integer sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum).get();        System.out.println("战斗力总和(方式2):" + sum2);        //求战斗力总和 方式3        Integer sum3 = personList.stream().map(Person::getSalary).reduce(0,Integer::sum);        System.out.println("战斗力总和(方式3):" + sum3);        //求年龄的乘积        Integer product  = personList.stream().map(Person::getAge).reduce((x,y) -> x * y).get();        System.out.println("年龄的乘积:" + product);        //求战斗力最大的值        Integer max  = personList.stream().map(Person::getSalary).reduce(1,Integer::max);        System.out.println("斗力最大的值:" + max);    }

运行结果:

(7)收集(collect)

收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。主要依赖java.util.stream.Collectors类内置的静态方法。

(8)归集(toList/toSet/toMap)

因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap是比较常见的用法

@Test    public void streamTest7() {        List<Person> personList = new ArrayList<Person>();        personList.add(new Person("鸣人", 8900, 18, "1", "螺旋丸"));        personList.add(new Person("佐助", 8800, 18, "1", "须佐能乎"));        personList.add(new Person("小樱", 7800, 17, "2", "治疗术"));        personList.add(new Person("自来也", 8200, 30, "1", "通灵术"));        personList.add(new Person("大蛇丸", 9500, 31, "1", "八岐大蛇"));        personList.add(new Person("纲手", 7900, 29, "2", "百豪之术"));        //必杀技list集合        List<String> list = personList.stream().map(person -> person.getArea()).collect(Collectors.toList());        System.out.println("必杀技集合toList:" + list);        //大于18的年龄set集合        Set<Integer> set = personList.stream().filter(person -> person.getAge() > 18).map(Person::getAge).collect(Collectors.toSet());        System.out.println("大于18的年龄集合toSet:" + set);        //战斗力大于8000的map集合 (写法1)        Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000)                .collect(Collectors.toMap(Person::getName, p -> p));        System.out.println("战斗力大于8000的集合toMap:" + map);        //战斗力大于8000的map集合 (写法2)        Map<?, Person> map2 = personList.stream().filter(p -> p.getSalary() > 8000)                .collect(Collectors.toMap(Person::getName, Function.identity()));        System.out.println("战斗力大于8000的集合toMap:" + map2);    }

运行结果:

总结

好了,以上就是我总结的Stream的常见用法,感谢大家的阅读,如果有什么疑问或者建议,欢迎评论区留下你的独到见解~

标签: #c语言stream