List 如何根據(jù)對象的屬性去重?JDK 8 Stream 輕松搞定(來長長見識(shí))
關(guān)注Java核心技術(shù),推送更多 Java 干貨!
作者:goodluckwj
來源:blog.csdn.net/qq_35634181/article/details/108867857
ExportTemperatureDto實(shí)體對象:
@Getter
@Setter
@ToString
public?class?ExportTemperatureDto?{
????private?String?name;
????private?Double?morningTemperature;
????private?Double?afternoonTemperature;
????private?String?classId;
????private?String?gradeId;
????private?Integer?personId;
}
在一個(gè)ExportTemperatureDto的集合中,根據(jù)personId屬性去重,生成一個(gè)新的集合。
import?static?java.util.Comparator.comparing;
import?static?java.util.stream.Collectors.collectingAndThen;
import?static?java.util.stream.Collectors.toCollection;
?
public?class?StreamTest?{
?
????public?static?void?main(String[]?args)?{
????????List?temperatureList?=?Lists.newArrayList();
????????temperatureList.add(new?ExportTemperatureDto(1,?"haha"));
????????temperatureList.add(new?ExportTemperatureDto(2,?"haha"));
????????temperatureList.add(new?ExportTemperatureDto(3,?"haha"));
????????temperatureList.add(new?ExportTemperatureDto(4,?"haha"));
?
????????temperatureList.add(new?ExportTemperatureDto(1,?"hahaasdas"));
????????temperatureList.add(new?ExportTemperatureDto(2,?"hahaasdas"));
?
????????List?result?=?temperatureList.stream()
????????????????.collect(
????????????????????????collectingAndThen(
????????????????????????????????toCollection(
????????????????????????????????????????()?->?new?TreeSet<>(comparing(ExportTemperatureDto::getPersonId))
????????????????????????????????),
????????????????????????????????ArrayList::new
????????????????????????)
????????????????);
?
????????result.forEach(System.out::println);
?
????????/*
????????????輸出結(jié)果為:
????????????????personId為1的,其名稱為haha
????????????????personId為2的,其名稱為haha
????????????因?yàn)門reeSet底層是使用TreeMap進(jìn)行實(shí)現(xiàn)的,傳入了根據(jù)getPersonId進(jìn)行比較的比較器
????????????在判斷personId相同時(shí),其比較結(jié)果為0,然后就會(huì)替換其value值,而key值是不會(huì)變化的,
????????????又因?yàn)門reeSet是將傳入的元素作為key的,所以使用TreeSet時(shí),當(dāng)比較器比較的結(jié)果相同時(shí),以不會(huì)將原來的值替換成比較后的值
?????????*/
?
????}
}
知其然知其所以然,這個(gè)stream流的操作看起來還是有點(diǎn)難度的,這里記錄一下。
使用到了collectingAndThen完成根據(jù)屬性進(jìn)行去重的操作,對于該去重操作的關(guān)鍵使用到了collectingAndThen、toCollection、TreeSet,有點(diǎn)難以理解,當(dāng)時(shí)我也是懵逼的,這里記錄一下,以后肯定還會(huì)用的到。
理解根據(jù)對象的屬性進(jìn)行去重的核心是,將集合放到TreeSet中,然后再將TreeSet轉(zhuǎn)為List, 其中TreeSet要傳入一個(gè)根據(jù)哪個(gè)屬性進(jìn)行比較的比較器,然后使用public ArrayList(Collection extends E> c)將TreeSet放入構(gòu)造器中生成List。最新面試題整理好了,點(diǎn)擊Java面試庫小程序在線刷題。
上面的Stream操作可以使用普通的集合:
TreeSet?treeSet?=?new?TreeSet<>(Comparator.comparing(ExportTemperatureDto::getPersonId));
for?(ExportTemperatureDto?temperatureDto?:?temperatureList){
????treeSet.add(temperatureDto);
}
List?result2?=??new?ArrayList<>(treeSet);
只要能夠理解普通集合怎么操作的,那么使用Stream流操作時(shí),就是要看對于API的使用是否熟悉,其實(shí)這個(gè)才是關(guān)鍵,只有理解了collectingAndThen、toCollection、JDK8的匿名函數(shù)這樣內(nèi)容,才能看懂這個(gè)式子。
關(guān)注Java核心技術(shù),推送更多 Java 干貨!
下面就簡單介紹一下:
首先說一下collectingAndThen方法的使用-------先進(jìn)行結(jié)果集的收集,然后將收集到的結(jié)果集進(jìn)行下一步的處理 ,紅字的兩句話是理解collectingAndThen的關(guān)鍵,首先看一下collectingAndThen需要傳遞的參數(shù):
public?static?Collector?
?????????collectingAndThen(Collector?downstream,
?????????Function?finisher)?
可以看到第一個(gè)參數(shù)是Collector接口的子類,所以還是對于對于Collector的處理,Collectors工具類里面的toList()、toSet()、joining()、mapping()、collectingAndThen()等幾乎所有的方法都可以使用,這樣感覺這個(gè)collectingAndThen就很強(qiáng)大了,可以嵌套的去使用。
第二個(gè)參數(shù)是一個(gè)Function函數(shù),熟悉的同學(xué)都知道,F(xiàn)unction函數(shù)是這樣的:R apply(T t),這個(gè)也是理解上面去重式子的關(guān)鍵,原來我想的是ArrayList::new調(diào)用的無參的構(gòu)造方法,其實(shí)他調(diào)用的ArrayList的有參構(gòu)造方法,
public?ArrayList(Collection?extends?E>?c)
調(diào)用的是上面那個(gè)構(gòu)造方法,這樣就很清晰,就是把第一個(gè)參數(shù)downstream的結(jié)果,交給第二個(gè)參數(shù)Function函數(shù)的參數(shù)里面,R apply(T t),也就是將結(jié)果設(shè)置成t。
對于toCollection是一個(gè)通用的轉(zhuǎn)為集合的操作,當(dāng)然在Collectors類里面也有toList()、toSet()方法,但是都不滿足于使用TreeSet來收集集合的方法,所以使用toCollection是一個(gè)通用的方法,使用TreeSet進(jìn)行收集,然后傳入根據(jù)哪個(gè)屬性進(jìn)行比較的比較器,這樣就可以了。
最近好文分享
1. 一個(gè)由 “YYYY-MM-dd” 引發(fā)的慘案 !
5. 妙用 Java 8 Function 接口,消滅 if...else
更多請關(guān)注???Java核心技術(shù)一個(gè)分享Java核心技術(shù)干貨的公眾號(hào)
點(diǎn)擊閱讀原文獲取免費(fèi)資料~