什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路
( short-circuiting)。 - 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
Stream 主要有四类接口:
- 流到流之间的转换:比如
filter(过滤):遍历stream每一个元素,过滤出符合传入的Predicate的元素stream;进入是stream,出来还是stream。
map(映射转换):遍历每一个元素,对每一个元素进行Function的操作处理
mapTo[Int|Long|Double] (到原子类型流的转换):遍历每一个元素,对每一个元素进行Function的操作处理
flatMap(高维结构平铺):map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap。
Stream< List< Integer > > inputStream = Stream.of(
Arrays.asList(1),
Arrays.asList(2, 3),
Arrays.asList(4, 5, 6)
);
Stream< Integer > outputStream = inputStream.
flatMap((childList) - > childList.stream());
flatMap 把 input Stream 中的层级结构扁平化,就是将最底层元素抽出来放到一起,最终 output 的新 Stream 里面已经没有 List 了,都是直接的数字。
flatMapTo[Int|Long|Double]:
distinct(不重复值):
peek(执行某种操作,流不变,可用于调试):
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
limit(限制到指定元素数量):
skip(跳过若干元素) :
- 流到值的转换
anyMatch (任一匹配):遍历stream每一个元素,只要有一个元素都符合Predicate返回true,都不符合返回false
allMatch(所有都匹配): 遍历stream每一个元素,所有元素都符合Predicate返回true,有一个不符合返回false
noneMatch(一个都不匹配): 遍历stream每一个元素,所有元素都不符合Predicate返回true,有一个符合返回false
findFirst(选择首元素):
findAny(任选一元素) : - 直接遍历: forEach (不保序遍历,比如并行流), forEachOrdered(保序遍历) ;
- 构造流: empty (构造空流),of (单个元素的流及多元素顺序流),iterate (无限长度的有序顺序流),generate (将数据提供器转换成无限非有序的顺序流), concat (流的连接), Builder (用于构造流的Builder对象)
class Student{
int id;
String name;
int age;
String sex;
int mathScore;
int chineseScore;
int totalScore;
int avgScore;
public Student(int id, String name, int age, String sex, int mathScore, int chineseScore) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
this.mathScore = mathScore;
this.chineseScore = chineseScore;
this.totalScore = mathScore + chineseScore;
this.avgScore = this.totalScore >> 1;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 int getMathScore() {
return mathScore;
}
public void setMathScore(int mathScore) {
this.mathScore = mathScore;
}
public int getChineseScore() {
return chineseScore;
}
public void setChineseScore(int chineseScore) {
this.chineseScore = chineseScore;
}
public int getTotalScore() {
return totalScore;
}
public void setTotalScore(int totalScore) {
this.totalScore = totalScore;
}
public int getAvgScore() {
return avgScore;
}
public void setAvgScore(int avgScore) {
this.avgScore = avgScore;
}
public String toString(){
return this.id+"-"+this.name+"-"+this.age+"-"+this.sex
+"-"+this.mathScore+"-"+this.chineseScore+"-"
+this.avgScore+"-"+this.totalScore;
}
}
public static void main(String[] args){
Student[] stu = new Student[8];
stu[0] = new Student( 2013356, "nsh", 25, "man", 135, 128);
stu[1] = new Student( 2013357, "yy", 24, "man", 134, 130);
stu[2] = new Student( 2013358, "zq", 25, "man", 135, 128);
stu[3] = new Student( 2013359, "wjh", 25, "man", 130, 118);
stu[4] = new Student( 2013355, "by", 26, "woman", 115, 148);
stu[5] = new Student( 2013354, "zy", 25, "woman", 145, 128);
stu[6] = new Student( 2013353, "zxf", 28, "woman", 105, 138);
stu[7] = new Student( 2013352, "cx", 22, "man", 135, 128);
List<Student> list = Arrays.asList(stu);
list.stream().filter(i->i.getAge()==28).forEach(i-> System.out.println(i));
list.stream().forEach(i-> System.out.println(i));
boolean s = list.stream().noneMatch(i->i.getAge()==28);
list.stream().map(i->i.getTotalScore()).collect(Collectors.toList()).stream().sorted((a,b)->b.compareTo(a)).forEach(i-> System.out.println(i));
Integer abs = list.stream().map(i->i.getAge()).collect(Collectors.toList()).stream().max((a,b)->a.compareTo(b)).get();
list.stream().map(i->i.getAge()).distinct().forEach(i-> System.out.println(i));
list.stream().filter(i->i.getAge()==28).peek(i-> System.out.println(i)).map(i->i).collect(Collectors.toList());
list.stream().skip(6).forEach(i-> System.out.println(i));
System.out.println(list.stream().findFirst().get().toString());
int aa = list.stream().filter(i->i.getSex()=="man").map(i->i.getAvgScore()).reduce(Integer.MAX_VALUE,Integer::min);
int ab = list.stream().filter(i->i.getSex()=="man").map(i->i.getAvgScore()).reduce(Integer::sum).get();
System.out.println(ab);
}
以上是StreamAPI的方法及其用法实例。