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() 第一个元素