Java8新特性:Stream
Stream是Java8中产生的一个新特性,可以把它理解成一种流,但也可以把它当做是一种特殊的容器
他可以结合Lambda表达式帮我们处理数据变得非常容易
一般来说使用它有三个步骤:
1、创建Stream
2、中间操作
3、终止操作(终端操作)
还是举个例子吧:
我们还是来遍历这个集合
List<Employee> list= Arrays.asList( new Employee("张三",18,5000), new Employee("李四",28,6000), new Employee("王五",48,4000), new Employee("马六",35,3000), new Employee("田七",25,3000), new Employee("田七",25,3000) );
我们之前用Lambda表达式可以用
list.foreach((e)->System.out.println(e))
现在可以使用另外一种方式:
list.stream() .foreach((e)->System.out.println(e))
或者是:
list.stream() .foreach(System.out::println)
后两种写法其实是一样的,第二种就是实现了抽象方法,第三种是进行了类方法引用
最后一句打印就是终止操作,如果一个流不进行终止的话,那么中间的数据操作是不会执行的
Stream.iterate(1,(x)->x+2).limit(10).forEach(System.out::println);
这个是产生无限流,要用limit进行限制,类似于python中的列表生成器
Stream的一些方法
- filter:参数是Lambda,可以利用他筛选出流内的一些数据
- limit:截断流,使其元素不超过给定数量
- skip:跳过元素,返回一个跳过前n个元素的流
- distinct:通过元素的hashcode方法和equals方法去除重复元素,一般要进行重写
示例:挑选出员工年龄大于30岁的人
list.stream() .filter((e)->e.getAge()>30) .foreach(System.out::println)
示例:取出年龄大于30岁的前3个
list.stream() .filter((e)->e.getAge()>30) .limit(3) .foreach(System.out::println)
示例:年龄大于30岁的前3个人不要
list.stream() .filter((e)->e.getAge()>30) .skip(3) .foreach(System.out::println)
示例:去重属性相同的人,去重规则需要重写hashcode方法和equals方法
list.stream() .filter((e)->e.getAge()>30) .distinct() .foreach(System.out::println)
Stream的映射
- map:函数参数为Lambda表达式,将流中每个数据进行指点方法进行处理,返回相对于的元素存入新流中
- flagmap:和map同理,但是有一点不同,当流中的每个元素是流时,用map就会进行两次遍历,类似于集合中的集合,就会遍历两遍,但是使用flagmap是就会将多个流合并成一个流,类似于集合中的addAll,他会将另外一个集合拆开,然后将每个元素再存入
List<String> list2=Arrays.asList("AF","sdf","Gd"); @Test public void test11(){ list2.stream() .map(Main::filterCharacter) .forEach((e)-> System.out.println(e)); } public static Stream<Character> filterCharacter(String str){ List<Character> list=new ArrayList<>(); for(Character ch:str.toCharArray()){ list.add(ch); } return list.stream(); } @Test public void test12(){ list2.stream() .flatMap(Main::filterCharacter) .forEach((e)-> System.out.println(e)); }
Stream排序
分为两种,自然排序和定制排序
第一种就是调用sorted方法,自动升序排序
但是要设计满足我们的需求,就要传入参数Lambda表达式,进行我们想要的操作,和实现Comparator的compare方法差不多
示例:优先按年龄排序从小到大,如果年龄相同则按照姓名字典序降序
list.stream() .sorted((e1,e2)->{ if(e1.getAge==e2.getAge){ return -e1.getName.compareTo(e2.getName); }else{ return Integer.compare(e1.getAge,e2.getAge); } }) .foreach(System.out::println);
Straem查找与匹配
- allMatch:检查是否匹配所有元素
- anyMatch:检查是否至少匹配一个元素
- noneMatch:检查是否没有匹配所有元素
- findFirst:返回第一个元素
- findAny:返回当前流中的任意元素
- count:返回流中元素的总个数
- max:返回流中最大值
- min:返回流中最小值
示例:
当我们要返回最大值时:
list.stream() .max((e1,e2)->Integer.compare(e1.getAge,e2.getAge)) .foreach(System.out::println)
示例:
当我们要年龄中大于30岁中任意一个人时:
list.stream() .filter((e)->e.getAge()>30) .findAny() .foreach(System.out.println)