java兩個(gè)List的交集,并集方式
java兩個(gè)List的交集,并集
方法一
- 使用apache的CollectionUtils工具類(推薦)
public static void main(String[] args) { String[] arrayA = new String[] { "1", "2", "3", "4"}; String[] arrayB = new String[] { "3", "4", "5", "6" }; List<String> listA = Arrays.asList(arrayA); List<String> listB = Arrays.asList(arrayB); //1、并集 union System.out.println(CollectionUtils.union(listA, listB)); //輸出: [1, 2, 3, 4, 5, 6] //2、交集 intersection System.out.println(CollectionUtils.intersection(listA, listB)); //輸出:[3, 4] //3、交集的補(bǔ)集(析?。ヾisjunction System.out.println(CollectionUtils.disjunction(listA, listB)); //輸出:[1, 2, 5, 6] //4、差集(扣除) System.out.println(CollectionUtils.subtract(listA, listB)); //輸出:[1, 2] }
方法二
- List自帶方法
public static void main(String[] args) { String[] arrayA = new String[] { "1", "2", "3", "4"}; String[] arrayB = new String[] { "3", "4", "5", "6" }; List<String> listA = Arrays.asList(arrayA); List<String> listB = Arrays.asList(arrayB); //1、交集 List<String> jiaoList = new ArrayList<>(listA); jiaoList.retainAll(listB); System.out.println(jiaoList); //輸出:[3, 4] //2、差集 List<String> chaList = new ArrayList<>(listA); chaList.removeAll(listB); System.out.println(chaList); //輸出:[1, 2] //3、并集 (先做差集再做添加所有) List<String> bingList = new ArrayList<>(listA); bingList.removeAll(listB); // bingList為 [1, 2] bingList.addAll(listB); //添加[3,4,5,6] System.out.println(bingList); //輸出:[1, 2, 3, 4, 5, 6] }
注意 : intersection和retainAll的差別
要注意的是它們的返回類型是不一樣的,intersection返回的是一個(gè)新的List集合,而retainAll返回是Bollean類型那就說(shuō)明retainAll方法是對(duì)原有集合進(jìn)行處理再返回原有集合,會(huì)改變?cè)屑现械膬?nèi)容。
個(gè)人觀點(diǎn):
1、從性能角度來(lái)考慮的話,List自帶會(huì)高點(diǎn),因?yàn)樗挥迷賱?chuàng)建新的集合。
2、需要注意的是:因?yàn)閞etainAll因?yàn)闀?huì)改變?cè)屑?所以該集合需要多次使用就不適合用retainAll。
注意:
Arrays.asList將數(shù)組轉(zhuǎn)集合不能進(jìn)行add和remove操作。
原因:
調(diào)用Arrays.asList()生產(chǎn)的List的add、remove方法時(shí)報(bào)異常,這是由Arrays.asList() 返回的市Arrays的內(nèi)部類ArrayList, 而不是java.util.ArrayList。
Arrays的內(nèi)部類ArrayList和java.util.ArrayList都是繼承AbstractList,remove、add等方法AbstractList中是默認(rèn)throw UnsupportedOperationException而且不作任何操作。
java.util.ArrayList重新了這些方法而Arrays的內(nèi)部類ArrayList沒(méi)有重新,所以會(huì)拋出異常。
- 所以正確做法如下
String[] array = {"1","2","3","4","5"}; List<String> list = Arrays.asList(array); List arrList = new ArrayList(list); arrList.add("6");
方法三
JDK1.8 stream 新特性
String[] arrayA = new String[] { "1", "2", "3", "4"}; String[] arrayB = new String[] { "3", "4", "5", "6" }; List<String> listA = Arrays.asList(arrayA); List<String> listB = Arrays.asList(arrayB); // 交集 List<String> intersection = listA.stream().filter(item -> listB.contains(item)).collect(toList()); System.out.println(intersection); //輸出:[3, 4] // 差集 (list1 - list2) List<String> reduceList = listA.stream().filter(item -> !listB.contains(item)).collect(toList()); System.out.println(reduceList); //輸出:[1, 2] // 并集 (新建集合:1、是因?yàn)椴挥绊懺技稀?、Arrays.asList不能add和remove操作。 List<String> listAll = listA.parallelStream().collect(toList()); List<String> listAll2 = listB.parallelStream().collect(toList()); listAll.addAll(listAll2); System.out.println(listAll); //輸出:[1, 2, 3, 4, 3, 4, 5, 6] // 去重并集 List<String> list =new ArrayList<>(listA); list.addAll(listB); List<String> listAllDistinct = list.stream().distinct().collect(toList()); System.out.println(listAllDistinct); //輸出:[1, 2, 3, 4, 5, 6]
總結(jié) : 這三種推薦第一種方式,因?yàn)榈诙N還需要確定該集合是否被多次調(diào)用。第三種可讀性不高。
對(duì)象集合交、并、差處理
因?yàn)閷?duì)象的equels比較是比較兩個(gè)對(duì)象的內(nèi)存地址,所以除非是同一對(duì)象,否則equel返回永遠(yuǎn)是false。
但我們實(shí)際開(kāi)發(fā)中 在我們的業(yè)務(wù)系統(tǒng)中判斷對(duì)象時(shí)有時(shí)候需要的不是一種嚴(yán)格意義上的相等,而是一種業(yè)務(wù)上的對(duì)象相等。在這種情況下,原生的equals方法就不能滿足我們的需求了,所以這個(gè)時(shí)候我們需要重寫equals方法。
說(shuō)明 :String為什么可以使用equels方法為什么只要字符串相等就為true,那是因?yàn)镾tring類重寫了equal和hashCode方法,比較的是值。
public class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } /** * 為什么重寫equals方法一定要重寫hashCode方法下面也會(huì)講 */ @Override public int hashCode() { String result = name + age; return result.hashCode(); } /** * 重寫 equals 方法 根據(jù)name和age都相同那么對(duì)象就默認(rèn)相同 */ @Override public boolean equals(Object obj) { Person u = (Person) obj; return this.getName().equals(u.getName()) && (this.age.equals(u.getAge())); } /** * 重寫 toString 方法 */ @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
這里根據(jù)name和age都相同那么就默認(rèn)相同對(duì)象。
public static void main(String[] args) { List<Person> personList = Lists.newArrayList(); Person person1 = new Person("小小",3); Person person2 = new Person("中中",4); personList.add(person1); personList.add(person2); List<Person> person1List = Lists.newArrayList(); Person person3 = new Person("中中",4); Person person4 = new Person("大大",5); person1List.add(person3); person1List.add(person4); /** * 1、差集 */ System.out.println(CollectionUtils.subtract(personList, person1List)); //輸出:[Person{name='小小', age=3}] /** * 2、并集 */ System.out.println(CollectionUtils.union(personList, person1List)); //輸出:[Person{name='小小', age=3}, Person{name='中中', age=4}, Person{name='大大', age=5}] /** * 3、交集 */ System.out.println(CollectionUtils.intersection(personList, person1List)); //輸出:[Person{name='中中', age=4}] /** * 4、交集的補(bǔ)集(析?。? */ System.out.println(CollectionUtils.disjunction(personList, person1List)); //輸出:[Person{name='小小', age=3}, Person{name='大大', age=5}] }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?Boot整合阿里開(kāi)源中間件Canal實(shí)現(xiàn)數(shù)據(jù)增量同步
這篇文章主要為大家介紹了Spring?Boot整合阿里開(kāi)源中間件Canal實(shí)現(xiàn)數(shù)據(jù)增量同步示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06java實(shí)現(xiàn)jdbc查詢結(jié)果集result轉(zhuǎn)換成對(duì)應(yīng)list集合
本文給大家匯總介紹了java實(shí)現(xiàn)jdbc查詢結(jié)果集result轉(zhuǎn)換成對(duì)應(yīng)list集合,十分的簡(jiǎn)單,有相同需求的小伙伴可以參考下。2015-12-12Java使用FilenameFilter查找出目錄下指定后綴的文件示例
這篇文章主要介紹了Java使用FilenameFilter查找出目錄下指定后綴的文件,結(jié)合實(shí)例形式分析了java基于FilenameFilter類的文件遍歷、查找相關(guān)操作技巧,需要的朋友可以參考下2019-10-10SpringBoot指標(biāo)監(jiān)控功能實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot指標(biāo)監(jiān)控功能實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(60)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-08-08