- Stream流?
结合Lambda表达式,用于简化集合和数组操作的API。
- Stream流的一个小例子:
- 创建一个集合,存储多个姓名,把集合中所有以"张"开头的长度为3的元素存储到一个新的集合并输出。
List<String> names=new ArrayList<>(); Collections.addAll(names,"张若虚","张仲景","李白","王维","张三"); System.out.println(names); //非Stream流 //find zhang List<String> zhang=new ArrayList<>(); for (String name : names) { if(name.startsWith("张")) zhang.add(name); } System.out.println(zhang); //find length is 3 List<String> three=new ArrayList<>(); for (String name : names) { if(name.length()==3) three.add(name); } System.out.println(three); //Stream流 //stream way lambda表达式 names.stream().filter(s -> s.startsWith("张")).filter(s->s.length()==3).forEach(s -> System.out.println(s));
可以看到通过Stream流方法代码简化到一行了。对于这一行Stream流方法代码可以分为三类方法:获取Stream流方法、中间方法、终结方法。
获取Stream流方法
- 集合得到Stream流:使用Stream()方法,例如示例的 names.stream()
- 数组得到Stream流:a,使用Stream()方法;b,使用Stream.of()
//1 Collection<String> list=new ArrayList<>(); Stream<String> Streamlist=list.stream(); //2 Map<String,Integer> maps=new HashMap<>(); Stream<String> StreamKey=maps.keySet().stream();//键的流 Stream<Integer> StreamVal=maps.values().stream();//值的流 Stream<Map.Entry<String,Integer>> StreamMaps=maps.entrySet().stream();//键值对的流 //3 Integer[] a={1,2,3,4,5}; Stream<Integer> ast= Arrays.stream(a);//a Stream<Integer> ast2=Stream.of(a);//b
中间方法
中间方法也称为非终结方法,调用完成后返回新的Stream流,支持链式编程。
常用中间方法API:
filter:对流中的数据进行过滤。
limit:获取前几个元素。
skip:跳过前几个元素。
distinct:去除流中重复的元素(hashCode和equals)。
concat:合并两个流。
Stream流中无法直接修改集合、数组中的数据。
终结方法
终结方法后流不可以继续使用
//执行示例的非终结流输出 System.out.println(names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3)); System.out.println(names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).count()); //控制台: java.util.stream.ReferencePipeline$2@3d075dc0 2
就是说没有添加终结方法会返回一个流stream,添加添加终结方法会返回具体内容。
常见终结操作:
forEach:流的每个元素执行遍历操作。
count:返回流中的元素数。
end.收集Stream流
把Stream流操作后的结果数据转回到集合或者数组中去,因为Stream流中无法直接修改集合、数组中的数据。
Stream流是方便操作集合、数组的手段,集合、数组才是目的。
一般方法:collect (可变集合)
具体方法:toList、toSet、toMap、toArray;
//继续示例的流: Stream<String> str=names.stream().filter(s -> s.startsWith("张")).filter(s->s.length()==3); List<String> z3List=str.collect(Collectors.toList());//collect List<String> z3List2=str.toList();//toList Object[] arrs=str.toArray();//toArray
其中toArray可以指定返回的对象类型,就可不使用Object来接收了。
String[] arrs=str.toArray(new IntFunction<String[]>() { @Override public String[] apply(int value) { return new String[0]; } });
!流只能使用一次,收集完就没了
stream has already been operated upon or closed