Java 獲取兩個List的交集和差集,以及應(yīng)用場景操作
背景介紹
在實際項目中,特別是一些管理后臺類的項目,會遇到底層數(shù)據(jù)是按照一對多關(guān)系的數(shù)據(jù)表存儲的管理界面。列表頁是一對多關(guān)系中一對應(yīng)的數(shù)據(jù)列表,二級的詳情頁中是一對多關(guān)系中多對應(yīng)的多條數(shù)據(jù)展示。通常二級頁面是能夠增、刪、改數(shù)據(jù)的編輯頁面,在點擊保存提交數(shù)據(jù)后,服務(wù)器端需要插入新增的數(shù)據(jù),刪除要刪除的數(shù)據(jù),更新改變的數(shù)據(jù)。
例如,在汽車電商領(lǐng)域,如果要實現(xiàn)一輛車型在不同省份有不同的價格行情,就需要有一個車價管理的后臺管理界面。每輛車對應(yīng)的詳情界面管理各省價格行情,增加該車在某個省份的行情,或者更新某個省份的行情,或者該車暫時去除某個省份的行情等功能,需要服務(wù)器端保證正確地數(shù)據(jù)存儲。
交集:指的是兩個List對象中都有的元素。
差集:指的是一個List對象中有,而另一個List對象中沒有的元素。
轉(zhuǎn)化為一般問題
在車價管理的車輛詳情頁面點擊保存各省行情按鈕后,請求會傳送一組數(shù)據(jù)到服務(wù)端,服務(wù)端把這組數(shù)據(jù)保存到一個List對象中。然后從數(shù)據(jù)庫中獲取該車型之前的各省行情數(shù)據(jù)并保存到List對象中,那么怎么找出哪些數(shù)據(jù)是要新增的,哪些數(shù)據(jù)是要刪除的,又有哪些數(shù)據(jù)是要更新的呢?
如果客戶端傳送的數(shù)據(jù)中有的省份行情數(shù)據(jù),而數(shù)據(jù)庫中沒有該省行情數(shù)據(jù)記錄,則這些數(shù)據(jù)是要插入數(shù)據(jù)庫中的。如果客戶端傳送的數(shù)據(jù)有的省份行情數(shù)據(jù),數(shù)據(jù)庫中也有改省的行情數(shù)據(jù),則這些數(shù)據(jù)是要更新的數(shù)據(jù)。如果數(shù)據(jù)庫中有的省份數(shù)據(jù),而客戶端傳送的數(shù)據(jù)中沒有改省份數(shù)據(jù),則這些數(shù)據(jù)是要刪除的。
經(jīng)過上述分析,不難發(fā)現(xiàn)就是找出兩個List對象的交集和差集。例如,a為客戶端傳送的數(shù)據(jù)List對象,b為從數(shù)據(jù)庫中獲取的List對象。 a中有的元素,而b中沒有的元素就是要插入數(shù)據(jù)庫中的數(shù)據(jù),即a與b的差集。a和b共有的元素就是要更新的數(shù)據(jù),即a與b的交集。b中有的元素,a中沒有的就是要刪除的數(shù)據(jù),即b與a的差集。
程序代碼
程序的大致思路是:利用LinkedHashMap key值的唯一性和順序存儲的特性,把provinceId作為key值,先用一個map添加一個List元素,然后再去比較另一個List對象中的元素,找出provinceId相同的對象和只有b中才有的對象。map中去除相同的key值的對象,剩余的就是a中獨有的元素。
各省行情類:
public class CarProvinceMarket {
private Integer id;
private Integer carId;
private Integer provinceId;
private Double price;
private Integer createdBy;
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getCarId() {
return carId;
}
public void setCarId(Integer carId) {
this.carId = carId;
}
public Integer getProvinceId() {
return provinceId;
}
public void setProvinceId(Integer provinceId) {
this.provinceId = provinceId;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
求兩個List對象交集、差集:
public class ListOperation {
public static void sameAndDifferentOperation(List<CarProvinceMarket> a, List<CarProvinceMarket> b, List<CarProvinceMarket> sameItems,
List<CarProvinceMarket> onlyAItems, List<CarProvinceMarket> onlyBItems){
if (a.isEmpty() && b.isEmpty()){
return;
}
LinkedHashMap<Integer, CarProvinceMarket> map = new LinkedHashMap<>();
LinkedHashMap<Integer, CarProvinceMarket> sameMap = new LinkedHashMap<>();
LinkedHashMap<Integer, CarProvinceMarket> onlyBMap = new LinkedHashMap<>();
for (CarProvinceMarket item: a){
map.put(item.getProvinceId(), item);
}
for (CarProvinceMarket item: b){
if (map.containsKey(item.getProvinceId())){
//如果要更新a中的記錄,則要更新map中的元素,并添加到sameMap
CarProvinceMarket carProvinceMarket = map.get(item.getProvinceId());
carProvinceMarket.setPrice(100000d);
sameMap.put(item.getProvinceId(), carProvinceMarket);
}else {
//新建的元素,需要設(shè)置相關(guān)成員變量
item.setCreatedBy(4);
onlyBMap.put(item.getProvinceId(),item);
}
}
sameItems.addAll(sameMap.values());
onlyBItems.addAll(onlyBMap.values());
for (CarProvinceMarket item: sameItems){
map.remove(item.getProvinceId());
}
onlyAItems.addAll(map.values());
}
public static void main(String [] args){
ArrayList<CarProvinceMarket> aCarProMar = new ArrayList<>();
ArrayList<CarProvinceMarket> bCarProMar = new ArrayList<>();
for (int i=0; i<1000000; i++){
CarProvinceMarket aCar = new CarProvinceMarket();
aCar.setProvinceId((i + 1)/2);
aCarProMar.add(aCar);
CarProvinceMarket bCar = new CarProvinceMarket();
bCar.setProvinceId((i + 2)/2);
bCarProMar.add(bCar);
}
LinkedList<CarProvinceMarket> sameItems = new LinkedList<>();
LinkedList<CarProvinceMarket> onlyAItems = new LinkedList<>();
LinkedList<CarProvinceMarket> onlyBItems = new LinkedList<>();
Long start = System.currentTimeMillis();
sameAndDifferentOperation(aCarProMar, bCarProMar, sameItems, onlyAItems, onlyBItems);
System.out.println("time = " + (System.currentTimeMillis() - start));
}
}
總結(jié)
在開發(fā)過程中,遇到問題要找出問題的一般性,轉(zhuǎn)化概念,理解本質(zhì),方能解決問題。
代碼鏈接: github
以上這篇Java 獲取兩個List的交集和差集,以及應(yīng)用場景操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringCloud如何使用Eureka實現(xiàn)服務(wù)之間的傳遞數(shù)據(jù)
這篇文章主要介紹了SpringCloud使用Eureka實現(xiàn)服務(wù)之間的傳遞數(shù)據(jù)操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
IntelliJ IDEA中顯示和關(guān)閉工具欄與目錄欄的方法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中顯示和關(guān)閉工具欄與目錄欄的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10

