Stream 和Collection结构化的数据不一样,Stream是一系列的元素,就像是生产线上的罐头一样,一串串的出来。
管道指的是一系列的聚合操作。
管道又分3个部分
管道源:在下面例子里,源是一个List
中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操作,并不会真正进行遍历。
结束操作:当这个操作执行后,流就被使用“光”了,无法再***作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回, 结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断
管道源
把Collection切换成管道源很简单,调用stream()就行了,数组需要使用Arrays.stream(list)
package stream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* 把Collection 转换成 管道源.
*/
public class StreamTest {
public static void main(String[] args){
List<Developer> developerList =getDevelopers();
developerList.stream().forEach(System.out::println);
System.out.println("---------");
Developer[] developers =developerList.toArray(new Developer[developerList.size()]);
Arrays.stream(developers).forEach(System.out::println);
/**
* 两个一样的
* public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
*/
Stream.of(developers).forEach(System.out::println);
}
private static List<Developer> getDevelopers(){
List<Developer> result = new ArrayList<>();
result.add(new Developer("mkyong", new BigDecimal("70000"), 33));
result.add(new Developer("alvin", new BigDecimal("80000"), 20));
result.add(new Developer("jason", new BigDecimal("100000"), 10));
result.add(new Developer("iris", new BigDecimal("170000"), 55));
return result;
}
}
传统方式过滤
package stream.fliter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* lambda 之前过滤一个list
*/
public class FilterListNormal {
public static void main(String[] args){
List<String> list = Arrays.asList("A","B","C","D");
List<String> result =getResultList(list,"B");
System.out.println("过滤 B 后");
result.forEach(System.out::println);
}
public static List<String> getResultList(List<String> list,String filter){
List<String> result = new ArrayList<>();
for(String str:list){
if(filter.equals(str)){
continue;//跳过
}
result.add(str);
}
return result;
}
}
管道中进行中间操作filter 过滤一个list
package stream.fliter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 在管道中进行中间操作 之 filter() 过滤一个list
* collect(Collectors.toList()) stream转换成List
*/
public class FilterListWithStream {
public static void main(String[] args){
List<String> list = Arrays.asList("A","B","C","D");
List<String> result = list.stream().filter(str->!"B".equals(str)).collect(Collectors.toList());
System.out.println("过滤 B 后");
result.forEach(System.out::println);
}
}
中间操作比较多,主要分两类
对元素进行筛选 和 转换为其他形式的流
对元素进行筛选:
filter 匹配
distinct 去除重复(根据equals判断)
sorted 自然排序
sorted(Comparator<T>) 指定排序
limit 保留
skip 忽略
转换为其他形式的流
mapToDouble 转换为double的流
map 转换为任意类型的流
Streams 中间操作filter(), 结束操作 findAny() and orElse()
传统的方式实现按条件找出
/**
* 按名字找到
*/
public class GetByNameNormal {
public static void main(String[] args){
List<Developer> list = Arrays.asList(
new Developer("cxy",new BigDecimal("10000"),21),
new Developer("da",new BigDecimal("10000"),21),
new Developer("fad",new BigDecimal("10000"),21),
new Developer("ef",new BigDecimal("10000"),21),
new Developer("ij",new BigDecimal("10000"),21),
new Developer("ui",new BigDecimal("10000"),21)
);
Developer result =getByName(list,"cxy");
System.out.println(result);
}
public static Developer getByName(List<Developer> list,String name){
Developer result =null;
for (Developer temp : list) {
if (name.equals(temp.getName())) {
result = temp;
}
}
return result;
}
}
使用 stream.filter().findAny().orElse(null) ,找不到返回null
其他常用的结束操作
常见结束操作如下:
forEach() 遍历每个元素
toArray() 转换为数组
min(Comparator<T>) 取最小的元素
max(Comparator<T>) 取最大的元素
count() 总数
findAny()
findFirst() 第一个元素