Java Stream map, Collectors(toMap, toList, toSet, groupingBy, collectingAndThen)使用案例
.map 以及 toList 方法聯(lián)合使用案例
/**
* .map .collect(Collectors.toList)
*/
private static void method2(){
List<MyPerson> collect = Stream.of("1:name1", "2:name2").map(new Function<String, MyPerson>() {
@Override
public MyPerson apply(String s) {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}).collect(Collectors.toList());
System.out.println(collect.toString());
}實(shí)際輸出
這里我重寫(xiě)了MyPerson 類的toString 等方法
[MyPerson{id=1, name='name1'}, MyPerson{id=2, name='name2'}]Stream.of(“1:name1”, “2:name2”) 譯為將多個(gè)of 中的元素轉(zhuǎn)為Stream 中的集合元素
.map 這里作用為將 Function中的第一個(gè)泛型元素也就是Stream 中的元素泛型,轉(zhuǎn)為 MyPerson 對(duì)象,這里 MyPerson 為我自己定義的對(duì)象,只有id 和 name 兩個(gè)屬性。 重寫(xiě)的方法 apply 為對(duì)每個(gè)Stream 中的String 元素的操作,并且通過(guò)這個(gè)方法將返回預(yù)期的 MyPerson 對(duì)象,即 .map 作用為將Stream 中的每一個(gè)元素轉(zhuǎn)為另一種元素的映射操作,實(shí)際就是一個(gè)轉(zhuǎn)換的中間方法。
.collect 說(shuō)明接下來(lái)要使用集合類操作 即使用了 Collectors.toList() 方法,該方法最終會(huì)將Stream 中的元素輸出為 List 類型的對(duì)象
上一案例 Collectors toMap使用
/**
* .map .collect(Collectors.toMap())
*/
private static void method3(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(new Function<String, MyPerson>() {
@Override
public MyPerson apply(String s) {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}).collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}實(shí)際輸出
{1=MyPerson{id=1, name='name1'}, 2=MyPerson{id=2, name='name2'}}
MyPerson{id=1, name='name1'}
MyPerson{id=2, name='name2'}
即 .collect(Collectors.toMap(MyPerson::getId, Function.identity()));
意義為使用集合方法中的toMap() 方法,toMap中,第一個(gè)參數(shù)為作為Map 的key, Function.identity() 對(duì)應(yīng)key 的值為 當(dāng)前元素自己,結(jié)果如上展示
上述案例也可以寫(xiě)為:map 中 可以直接使用lambda 表達(dá)式給出返回結(jié)果 s 即Stream 中的每個(gè)元素
/**
* .map .collect(Collectors.toMap()) lambda
*/
private static void method4(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(s -> {
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}).collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}上述案例
可以進(jìn)一步簡(jiǎn)寫(xiě)為:即 .map 中可以直接使用引用某一已經(jīng)存在的方法來(lái)獲取結(jié)果 MyPerson::transEntity 見(jiàn)末尾MyPerson 中定義的方法
/**
* .map .collect(Collectors.toMap()) lambda level up MapTrans
*/
private static void method5(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(MyPerson::transEntity)
.collect(Collectors.toMap(MyPerson::getId, Function.identity()));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}其中 Function.identity() 也可以如下寫(xiě)法 s -> s 也表示直接獲取當(dāng)前對(duì)象作為 Map的值
/**
* .map .collect(Collectors.toMap()) lambda level up MapTrans
*/
private static void method6(){
Map<Integer, MyPerson> collect = Stream.of("1:name1", "2:name2").map(MyPerson::transEntity)
.collect(Collectors.toMap(MyPerson::getId, s -> s));
System.out.println(collect.toString());
MyPerson myPerson = collect.get(1);
System.out.println(myPerson);
MyPerson myPerson1 = collect.get(2);
System.out.println(myPerson1.toString());
}toList 使用案例
private static void lambdaTestToList(){
String m = "a,b,c,d,d,d,d,d";
Stream.of("a", "aa", "aaa", "b", "bb", "bbb").collect(Collectors.toList()).forEach((item) -> {
System.out.println(item);
});
System.out.println("*******************");
Stream.of(m.split(",")).collect(Collectors.toList()).forEach((item) -> {
System.out.println(item);
});
System.out.println("*******************");
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
List<MyPerson> list = new ArrayList<>();
list.add(myPerson);
list.add(myPerson2);
list.add(myPerson1);
List<List<MyPerson>> collect = Stream.of(list).collect(Collectors.toList());
List<Object> collect1 = Stream.of(list.toArray()).collect(Collectors.toList());
System.out.println("*******************");
collect.stream().forEach(item -> {
System.out.println(item.toString());
});
System.out.println("*******************");
collect1.stream().forEach(item -> {
System.out.println(item);
});
}輸出結(jié)果:
a
aa
aaa
b
bb
bbb
*******************
a
b
c
d
d
d
d
d
*******************
*******************
[MyPerson{id=1, name='545'}, MyPerson{id=3, name='445'}, MyPerson{id=2, name='333'}]
*******************
MyPerson{id=1, name='545'}
MyPerson{id=3, name='445'}
MyPerson{id=2, name='333'}Process finished with exit code 0
可以看的出常見(jiàn)的 逗號(hào)拼接方式的字符串也可以通過(guò) toList 快速轉(zhuǎn)為我們常用的 list 形式并做一定的操作
toSet
上述案例中直接list 轉(zhuǎn) set 做去重和類型轉(zhuǎn)換十分快捷
// 定義
private static String arrayStr = "1,2,3,4, 5,6,7";
private static String arrayStrEN = "a,b,c,d,d,d,f";
private static List<MyPerson> listObject = new ArrayList<>();
private static List<JSONObject> listJsonObject = new ArrayList<>();
static {
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
MyPerson myPerson3 = new MyPerson(2, "333");
listObject.add(myPerson);
listObject.add(myPerson1);
listObject.add(myPerson2);
listObject.add(myPerson3);
JSONObject object = new JSONObject();
object.put("dep", 124);
object.put("userId", "14");
object.put("names", "aka");
JSONObject object1 = new JSONObject();
object1.put("dep", 124);
object1.put("userId", "14");
object1.put("names", "aka1");
JSONObject object2 = new JSONObject();
object2.put("dep", 125);
object2.put("userId", "15");
object2.put("names", "aka2");
JSONObject object3 = new JSONObject();
object3.put("dep", 125);
object3.put("userId", "15");
object3.put("names", "aka3");
JSONObject object4 = new JSONObject();
object4.put("dep", 136);
object4.put("userId", "14");
object4.put("names", "aka4");
listJsonObject.add(object);
listJsonObject.add(object1);
listJsonObject.add(object2);
listJsonObject.add(object3);
listJsonObject.add(object4);
}
public static void lambdaToSet(){
Stream.of(arrayStr.split(",")).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item.trim());
});
System.out.println("---------------");
Stream.of(arrayStrEN.split(",")).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item.trim());
});
System.out.println("-----------");
Stream.of(listObject.toArray()).collect(Collectors.toSet()).forEach(item -> {
System.out.println(item);
});
}輸出結(jié)果:
1
2
3
4
5
6
7
---------------
a
b
c
d
f
-----------
MyPerson{id=2, name='333'}
MyPerson{id=3, name='445'}
MyPerson{id=1, name='545'}
groupingBy collectingAndThen 使用
// 定義
private static List<MyPerson> listObject = new ArrayList<>();
private static List<JSONObject> listJsonObject = new ArrayList<>();
static {
MyPerson myPerson = new MyPerson(1, "545");
MyPerson myPerson1 = new MyPerson(2, "333");
MyPerson myPerson2 = new MyPerson(3, "445");
MyPerson myPerson3 = new MyPerson(2, "333");
listObject.add(myPerson);
listObject.add(myPerson1);
listObject.add(myPerson2);
listObject.add(myPerson3);
JSONObject object = new JSONObject();
object.put("dep", 124);
object.put("userId", "14");
object.put("names", "aka");
JSONObject object1 = new JSONObject();
object1.put("dep", 124);
object1.put("userId", "14");
object1.put("names", "aka1");
JSONObject object2 = new JSONObject();
object2.put("dep", 125);
object2.put("userId", "15");
object2.put("names", "aka2");
JSONObject object3 = new JSONObject();
object3.put("dep", 125);
object3.put("userId", "15");
object3.put("names", "aka3");
JSONObject object4 = new JSONObject();
object4.put("dep", 136);
object4.put("userId", "14");
object4.put("names", "aka4");
listJsonObject.add(object);
listJsonObject.add(object1);
listJsonObject.add(object2);
listJsonObject.add(object3);
listJsonObject.add(object4);
}
public static void lambdaGroupBy(){
System.out.println("--------------按某一屬性分組 返回key Object 的Map");
Map<Integer, List<MyPerson>> collect = listObject.stream().collect(Collectors.groupingBy(MyPerson::getId));
System.out.println(collect.toString());
System.out.println("--------------按某些屬性的組合作為鍵 返回key Object的Map");
Map<String, List<MyPerson>> collect1 = listObject.stream().collect(Collectors.groupingBy(myPerson -> myPerson.getId() + myPerson.getName() + ""));
System.out.println(collect1.toString());
System.out.println("--------------按JSON 的某些屬性組合作為鍵 返回key Object的Map");
Map<String, List<JSONObject>> collect2 = listJsonObject.stream().collect(Collectors.groupingBy(item -> item.get("dep") + item.getString("userId")));
System.out.println(collect2);
System.out.println("--------------按某一屬性分組后, 獲取當(dāng)前分組后Map的size 可用于統(tǒng)計(jì)");
Integer collect3 = listObject.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(MyPerson::getId), Map::size));
System.out.println(collect3);
}main 中運(yùn)行 lambdaGroupBy
輸出結(jié)果如下:
--------------按某一屬性分組 返回key Object 的Map
{1=[MyPerson{id=1, name='545'}], 2=[MyPerson{id=2, name='333'}, MyPerson{id=2, name='333'}], 3=[MyPerson{id=3, name='445'}]}
--------------按某些屬性的組合作為鍵 返回key Object的Map
{1545=[MyPerson{id=1, name='545'}], 3445=[MyPerson{id=3, name='445'}], 2333=[MyPerson{id=2, name='333'}, MyPerson{id=2, name='333'}]}
--------------按JSON 的某些屬性組合作為鍵 返回key Object的Map
{12515=[{"names":"aka2","userId":"15","dep":125}, {"names":"aka3","userId":"15","dep":125}], 12414=[{"names":"aka","userId":"14","dep":124}, {"names":"aka1","userId":"14","dep":124}], 13614=[{"names":"aka4","userId":"14","dep":136}]}
--------------按某一屬性分組后, 獲取當(dāng)前分組后Map的size 可用于統(tǒng)計(jì)
3
groupingBy 用意為將每一個(gè)元素按照某一種屬性或多種屬性執(zhí)行分組操作,返回為map key 為分組的屬性條件,值為當(dāng)前元素
collectingAndThen 即執(zhí)行集合操作后再執(zhí)行某一方法
總結(jié)
通過(guò) stream 使一般的集合對(duì)象成為可以執(zhí)行Stream 操作的對(duì)象map 將每一個(gè)元素通過(guò)某些操作轉(zhuǎn)化為另一種元素
Collectors 中
toMap 將每一種元素轉(zhuǎn)為Map類型的結(jié)構(gòu),可以通過(guò)鍵拿到對(duì)應(yīng)的元素,這里相當(dāng)于是 數(shù)據(jù)庫(kù)中通過(guò)id 獲取某一條記錄的數(shù)據(jù)一樣,相當(dāng)于自己建立了一個(gè)數(shù)據(jù)索引,對(duì)于數(shù)據(jù)暫存和優(yōu)化以及操作十分方便,而且可以省去繁瑣的簡(jiǎn)單操作將數(shù)據(jù)轉(zhuǎn)為這一數(shù)據(jù)結(jié)構(gòu)的過(guò)程,而且符合獲取數(shù)據(jù)時(shí)的習(xí)慣。
toList 快速將多個(gè)元素轉(zhuǎn)為L(zhǎng)ist 而不用自己執(zhí)行遍歷操作
toSet 快速將多個(gè)元素轉(zhuǎn)為set集合 可以用于去重操作
groupingBy 通過(guò)該方法可以快速對(duì)數(shù)據(jù)分組,同樣省去了自己封裝簡(jiǎn)單代碼的過(guò)程
collectingAndThen 集合類操作和其他結(jié)果的聚合操作,同時(shí)是為了提升效率
雖然一般情況下不需要考慮代碼的速度問(wèn)題,但這里還是說(shuō)一下Stream 的使用場(chǎng)景經(jīng)過(guò)對(duì)比,其實(shí)最簡(jiǎn)單的循環(huán)迭代方式對(duì)于較少和較簡(jiǎn)單的數(shù)據(jù)來(lái)說(shuō) for 等基本操作反而花費(fèi)的時(shí)間是要比 Stream 快的。
這里我理解 Stream 是使用時(shí)間換來(lái)了代碼的優(yōu)化和簡(jiǎn)潔,但是對(duì)于不常使用Stream的人來(lái)說(shuō)易讀性并不太友好。
Stream 使用場(chǎng)景如下:
- 在循環(huán)迭代次數(shù)較少的情況下,常規(guī)的迭代方式性能反而更好
- 在單核CPU服務(wù)器配置環(huán)境中,常規(guī)迭代方式更有優(yōu)勢(shì)
- 在大數(shù)據(jù)循環(huán)迭代中,如果服務(wù)器是多核CPU的情況,采用Stream的并行迭代優(yōu)勢(shì)明顯
MyPerson對(duì)象定義
equals hashCode 為了對(duì)象比較一定需要重寫(xiě) 直接使用代碼生成的即可
import java.util.Objects;
public class MyPerson {
private int id;
private String name;
public MyPerson() {
}
public MyPerson(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyPerson{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyPerson myPerson = (MyPerson) o;
return id == myPerson.id &&
Objects.equals(name, myPerson.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
public static MyPerson transEntity(String s){
String[] split = s.split(":");
MyPerson myPerson = new MyPerson(Integer.valueOf(split[0]), split[1]);
return myPerson;
}
}到此這篇關(guān)于Java Stream map, Collectors(toMap, toList, toSet, groupingBy, collectingAndThen)使用案例的文章就介紹到這了,更多相關(guān)Java Stream map, Collectors內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信開(kāi)發(fā)--自定義菜單查詢返碼亂碼的解決方法
本篇文章主要介紹了微信開(kāi)發(fā)--自定義菜單查詢返碼亂碼的解決方法,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03
Java實(shí)現(xiàn)對(duì)象復(fù)制的方法實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)對(duì)象復(fù)制的方法實(shí)例,深復(fù)制:復(fù)制出來(lái)的對(duì)象中的變量(包括基本類型和字符串)和原來(lái)的對(duì)象的值都相同,引用對(duì)象也會(huì)指向復(fù)制出來(lái)的對(duì)象,需要的朋友可以參考下2023-08-08
logback-spring.xml的內(nèi)容格式詳解
這篇文章主要介紹了logback-spring.xml的內(nèi)容格式詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的的朋友參考下吧2023-11-11
java智能問(wèn)答圖靈機(jī)器人AI接口(聚合數(shù)據(jù))
這篇文章主要介紹了java智能問(wèn)答圖靈機(jī)器人AI接口(聚合數(shù)據(jù)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
如何基于java實(shí)現(xiàn)Gauss消元法過(guò)程解析
這篇文章主要介紹了如何基于java實(shí)現(xiàn)Gauss消元法過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
java中線程池最實(shí)用的創(chuàng)建與關(guān)閉指南
試中經(jīng)常會(huì)問(wèn)到,創(chuàng)建一個(gè)線程池需要哪些參數(shù)啊,線程池的工作原理啊,卻很少會(huì)問(wèn)到線程池如何安全關(guān)閉的,下面這篇文章主要給大家介紹了關(guān)于java中線程池最實(shí)用的創(chuàng)建與關(guān)閉的相關(guān)資料,需要的朋友可以參考下2021-09-09

