Stream 是Java8的新特性,它允许你以声明式的方式处理数据集合,可以把它看作是遍历数据集的高级迭代器。此外与stream与lambada表达示结合后编码效率与大大提高,并且可读性更强。
说明想要完成什么(筛选,排序,取值),而不说明如何实现一个操作(for循环)。同时可以将这些操作链接起来,达到一种流水线式的效果。
数据处理操作:流更偏向于数据处理和计算,比如filter、map、find、sort 等。简单来说,我们通过一个集合的stream方法获取一个流,然后对流进行一系列流操作,最后再构建成我们需要的数据集合。一般分为中间操作和终端操作。
public class Empl implements Comparable<Empl>{
private String number;
private String name;
private String sex;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Empl(String number, String name, String sex) {
this.number = number;
this.name = name;
this.sex = sex;
}
@Override
public int compareTo(Empl empl) {
return empl.getNumber().compareTo(this.getNumber());
}
}
private static List<Empl> getEmplList() {
List<Empl> EmplList=new ArrayList<>();
EmplList.add(new Empl("1111","张三","男"));
EmplList.add(new Empl("2222","李四","男"));
EmplList.add(new Empl("3333","王娟","女"));
EmplList.add(new Empl("4444","王小莉","女"));
return EmplList;
}
一、中间操作
filter : Stream进行过滤操作,用于通过满足指定条件的元素生成新的Stream。其格式为“filter(Predicate<? super T> predicate)”,Predicate是函数式接口,表示一个参数T,返回boolean值的函数。这就代表,只有满足Predicate 判断表达式的才能被放进新的Stream。
List<Empl> filterlist =EmplList.stream()//获取流
.filter(empl -> empl.getName().startsWith("王"))//中间操作
.collect(Collectors.toList());//把流转化为新的集合,也称为终端操作
sorted(Comparator<? super T>
comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。
注意sorted是一个有状态的中间操作,即,只有全部执行完所有的数据才能知道结果。
//按职员编码排序
List<Empl> orderlist=EmplList.stream()//获取流
.sorted(Comparator.comparing(Empl::getNumber))//中间操作
.collect(Collectors.toList());//把流转化为新的集合,也称为终端操作
orderlist.stream().forEach(empl -> System.out.println(empl.getNumber()));
//多字段排序,先按编码降序排,再按名称排
List<Empl> order1list=EmplList.stream()//获取流
.sorted(Comparator.comparing(Empl::getNumber,Comparator.reverseOrder())
.thenComparing(Empl::getName))//中间操作
.collect(Collectors.toList());//把流转化为新的集合,终端操作
order1list.stream().forEach(empl -> System.out.println(empl.getNumber()));
//按指定顺序排序,并且获取名称列表字符串
String names=EmplList.stream()//获取流
.sorted(Comparator.comparing(s->{return s.getNumber()+s.getName();},
Comparator.reverseOrder()))//中间操作
.map(Empl::getName)//中间操作
.collect(Collectors.joining(",","[","]"));////把流转化为新的集合,终端操作
limit(n):它接受一个long类型的参数n,表示限制的数量。调用limit函数后,返回一个新的流,它仅包含原流中前n个元素。
EmplList.stream().limit(2).forEach(empl ->{
System.out.println(empl.getNumber());
} );
skip(n):它接受一个long类型的参数n,表示需要跳过的数量。调用skip函数后,返回一个新的流,它跳过原流中的前n个元素。
EmplList.stream().skip(2).forEach(empl ->{
System.out.println(empl.getNumber());
} );
map(): 将其映射成一个新的元素。
// 1.以map的数据格式获取所有职员的名称
// 2.然后把所有的名称放到一个collect集合中,然后转为List类型
// 3.最后判断该List中是否包含字符串"王娟"
boolean flag=EmplList.stream()
.map(Empl::getName)
.collect(Collectors.toList()).contains("王娟");
二、终端操作
forEach:遍历流中的元素
EmplList.stream().forEach(empl -> System.out.println(empl.getName()));
toArray:将流中的元素倒入一个数组
Min:返回流中元素最小值
Max:返回流中元素最大值
使用max或min方法获取集合中的最大值或者最小值后,方法将返回一个Optional对象,这个Optional对象中可能包含了集合中的最大值,也有可能没有。因此,在获取结果前,我们需要先对Optional对象进行判断:
//求number最大值
Optional<Empl> maxEmpl=EmplList.stream().max(Comparator.comparing(s -> {
return s.getNumber();
}));
if(maxEmpl.isPresent()){
System.out.println("maxEmpl==="+maxEmpl.get().getNumber());
}
//求number最小值
Optional<Empl> minEmpl=EmplList.stream().min(Comparator.comparing(s -> {
return s.getNumber();
}));
if(minEmpl.isPresent()){
System.out.println("maxEmpl==="+minEmpl.get().getNumber());
}
count:返回流中元素的总个数。
anyMatch:接收一个Predicate函数,只要流中有一个元素满足条件则返回true,否则返回。
allMatch:接收一个Predicate函数,当流中每个元素都符合条件时才返回true,否则返回false。
noneMatch:与allMatch相反,判断条件里的元素,所有的都不是,返回true。
boolean anyMatch = EmplList.stream().anyMatch(empl -> empl.getName().startsWith("王"));
boolean allMatch = EmplList.stream().allMatch(empl -> empl.getName().startsWith("王"));
boolean noneMatch = EmplList.stream().noneMatch(empl -> empl.getName().startsWith("王"));
long count = EmplList.stream().filter(empl-> empl.getName().startsWith("王")).count();
System.out.println("anyMatch==="+anyMatch);
System.out.println("allMatch==="+allMatch);
System.out.println("noneMatch==="+noneMatch);
System.out.println("count==="+count);
findFirst:返回流中第一个元素
collect:将流中的元素倒入一个集合。