记录一次学习Stream API特性的笔记。
一、集合处理数据弊端
以往我们对集合进行操作时,往往要使用for或者foreach循环对集合进行遍历,非常不便利,使用Stream API之后,就可一直接调用.stream().filter()....foreach()等方法进行操作,就可以达成效果。总之,一句话,stream可以让我们快速完成许多复杂的工作,比如筛选、切片、映射、查找、去重、统计、匹配和规约等,用比以往更少的代码量完成任务。
二、Stream流式思想概述
首先,Stream流区别于传统的IO流,并不是一种数据结构,不保存数据,而是对数据进行加工处理,Stream流类似于工厂车间的流水线,stream相当于流水线上的一道工序,如此通过多道工序让原材料加工成一个商品。
如此,如果是为了日常工作中的任务的话,理论知识了解到这就可以了,主要是下面的应用知识。
三、Stream流获取方式
1、通过.stream()方法获取
java.util.collection接口中有一个默认方法:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
也就是说collection接口下的所有实现都可以使用.stream()方法来获取stream流对象。
于是:
list集合获取:
List<String> list=new ArrayList<>();
list.stream();
set集合获取:
Set<String> set=new HashSet<>();
set.stream();
map集合获取:
Map<String, Object> map=new HashMap<>();
Stream<String> keyStream=map.keySet().stream();
Stream<Object> valuesStream=map.values().stream();
Stream<Map.Entry<String,Object>> Stream=map.entrySet().stream();
2、Stream.of()方法
操作对象:数组,需要注意,基本数据类型的数组是不行的。
Stream<String> a1=Stream.of("a1","a2","a3");
四、常用方法
在说常用方法之前先简要说一下注意事项。
1)终结方法:返回值类型不再是Stream类型的方法,不在支持链式调用。
2)非终结方法:返回值类型仍然是Stream类型的方法,支持链式调用。
3)Stream只能操作一次
4)Stream方法返回的是最新的流
5)Stream不调用终结方法,中间的操作不会执行
常用方法;
1、foreach()方法
forEach()方法是用来遍历流中数据的,该方法接受一个Consumer接口,会将每一个流交给函数处理。终结方法。
Stream.of("a1","a2","a3").forEach(System.out::println);
2、count()方法
Stream流中的count方法用来统计其中元素个数的。终结方法。
long count=Stream.of("a1","a2","a3").count();
3、filter()方法
将流转换为子集流。该接口接受一个Predicate函数式接口参数作为筛选条件。非终结方法。
Stream.of("a1","a2","a3","bb","cc","dd","abc").filter((s) -> s.contains("a")).forEach(System.out::println);
结果:
a1
a2
a3
abc
4、limit()方法
对流进行截取处理,只取前N个数据,参数是一个long类型的数据,如果集合长度大于参数就进行截取,否则不进行操作。非终结方法。
Stream.of("a1","a2","a3","bb","cc","dd","abc").limit(2).forEach(System.out::println);
//结果
a1
a2
5、skip()方法
跳过前几个元素,可以使用该方法获取一个截取之后的新流。非总结方法。
Stream.of("a1","a2","a3","bb","cc","dd","abc").skip(4).forEach(System.out::println);
//结果
cc
dd
abc
6、map()方法
可以将流中的元素映射到另一个流中去,该接口需要一个Function函数式的接口参数,可以将当前流中的T类型数据转换为另一种R类型数据。非终结方法。
Stream.of("1","2","3","4","5","6","7").map(Integer::parseInt).forEach(System.out::print);
7、sorted()方法
可以将数组排序,可根据自然顺序排序,也可通过比较来强指定排序规则。非终结方法。
Stream.of("10","20","13","44","56","16","27").map(Integer::parseInt)
// .sorted()//自然顺序排序
.sorted(((o1, o2) -> o2-o1))//降序排序
.forEach(System.out::println);
8、distinct()方法
对于基本数据类型可以直接去重,但是对于自定义类型,需要重写hashcode()方法和equals()方法
来去重。非终结方法。
Stream.of("10","20","13","44","56","16","27","16").map(Integer::parseInt)
// .sorted()//自然顺序排序
.sorted(((o1, o2) -> o2-o1))//降序排序
.distinct()
.forEach(System.out::println);
}
9、reduce()方法
可将所有数据归纳得到一个数据。非终结方法。
Integer sum=Stream.of(12,99,23,19).reduce(0,(x,y)->{
System.out.println("x="+x+",y="+y);
return x+y;
}); //0为默认值,第一次时会自动将默认值赋值给x,此时x=0,y是每次从数据中获取的元素,第一次是4。之后每次会将上一次的操作结果赋值给x。最终得到所有元素相加的和。
System.out.println(sum);
System.out.println("--------------------------------------------------------");
//获取最大值
Integer max=Stream.of(34,4,56,26,7).reduce(0,(x,y)->{
return x>y?x:y;
});
System.out.println(max);
结果:
x=0,y=12
x=12,y=99
x=111,y=23
x=134,y=19
153
--------------------------------------------------------
56