一、開篇
- Stream?其實(shí)就是處理集合的一種形式,稱之為流,在Java8中被引入,可被Collection中的子類調(diào)用。
- 作用?簡化代碼,提升你的開發(fā)效率。
- 不會?看完這篇你就能自己上手了!
二、實(shí)例
首先將你的集合處理成流,才可以使用此API。
Stream<String> stream = list.stream();

接下來創(chuàng)建一個String類型的List,便于測試。
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(7);
list.add(4);
list.add(6);

接下來展示具體參數(shù)使用方式。
- filter 過濾
例:需要過濾出在集合中,大于5的數(shù)字的集合。
List<Integer> result = list.stream().filter(o -> o>5).collect(Collectors.toList());

filter內(nèi)部使用的是lamda表達(dá)式,也是Java8的功能,o代表集合中每一個元素,o>5表示這個元素的值若大于5就返回true,就獲取結(jié)果。collect表示聚合,Collectors.toList()表示將結(jié)果聚合到一個List集合。
- map 形成一個新對象
例:需要將集合內(nèi)的元素全部轉(zhuǎn)換成String類型。
List<String> result = list.stream().map(o->String.valueOf(o)).collect(Collectors.toList());

- sort 排序
例: 需要從小到大排序。
List<Integer> result = list.stream().sorted().collect(Collectors.toList());

例: 需要從大到小排序。
List<Integer> result = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

- forEach 遍歷
例: 打印集合內(nèi)每個元素。
list.stream().forEach(o->System.out.println(o));
list.forEach(o->System.out.println(o));

- distinct 去除重復(fù)元素
List<Integer> result = list.stream().distinct().collect(Collectors.toList());

- reduce 集合內(nèi)運(yùn)算
例: 計算集合中元素的和。
Integer sum = list.stream().reduce(0, (i, j) -> i + j);

reduce中第一個參數(shù)為基數(shù),即為初始值,i,j的定義為第一個和第二個操作數(shù),i+j即為操作,此處為加法操作。
如果計算乘法,就不能設(shè)置初始值為0,因?yàn)?乘任何數(shù)都為0。
- collect 聚合成Collection
- Collectors.toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)
- Collectors.toList()
- Collectors.toSet()
- ...
例: 將list聚合成一個key為元素,value為“item”+元素的Map。
Map<Integer, String> map = list.stream().collect(Collectors.toMap(Function.identity(), o -> String.format("item%s", o)));

結(jié)果:{1=item1, 2=item2, 3=item3, 4=item4, 6=item6, 7=item7}
keyMapper表示設(shè)置為key的規(guī)則,valueMapper表示設(shè)置為value的規(guī)則。
Function.identity()表示當(dāng)前本身元素。
- groupBy 分組
Collectors.groupingBy(Function<? super T, ? extends K> classifier)
新建一個User實(shí)體,有姓名和年齡兩個字段,并初始化一個集合便于測試。
List<User> list = new ArrayList<User>();
list.add(new User("與李", 18));
list.add(new User("CSDN", 19));
list.add(new User("han", 20));
list.add(new User("han", 21));

例: 需要把名字相同的實(shí)體提出來放在一起,形成一個List集合。
Map<String, List<User>> group = list.stream().collect(Collectors.groupingBy(User::getName));

結(jié)果:{han=[User [name=han, age=20], User [name=han, age=21]], CSDN=[User [name=CSDN, age=19]], 與李=[User [name=與李, age=18]]}
此處使用User實(shí)體的name屬性進(jìn)行分組。
User::getName 與 o -> o.getName() 含義相同,兩者皆可傳入。
- partitioningBy 分區(qū)
Collectors.partitioningBy(Predicate<? super T> predicate)
例: 分別統(tǒng)計年齡大于等于20和小于20的學(xué)生信息
Map<Boolean, List<User>> partitioning = list.stream().collect(Collectors.partitioningBy(o -> o.getAge() >= 20));

結(jié)果:{false=[User [name=與李, age=18], User [name=CSDN, age=19]], true=[User [name=han, age=20], User [name=han, age=21]]}
可以看到返回結(jié)果是一個Map<Boolean, List<User>>,利用partitioningBy后生成的map,有且僅有兩個元素,key固定為true和false,分別表示滿足條件的信息和不不滿足條件的信息。
三、結(jié)尾
此文列舉了Stream部分方法的使用,具體更多的方法需要自己去深入了解。通過熟悉使用Stream的api之后,你會對它的處理方式愛不釋手。