Java?List集合取交集的8種不同實(shí)現(xiàn)方式總結(jié)

方法一:使用Java 8的Stream API
這種方法利用Stream API的filter和collect操作來找到兩個(gè)列表的交集。
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
List<Integer> intersection = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
方法二:使用傳統(tǒng)的for循環(huán)遍歷
這種方法通過遍歷一個(gè)列表,并檢查其元素是否存在于另一個(gè)列表中來實(shí)現(xiàn)交集。
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
List<Integer> intersection = new ArrayList<>();
for (Integer item : list1) {
if (list2.contains(item)) {
intersection.add(item);
}
}
使用HashSet優(yōu)化遍歷方法:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ListIntersection {
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
Set<Integer> set1 = new HashSet<>(list1);
List<Integer> intersection = new ArrayList<>();
for (Integer num : list2) {
if (set1.contains(num)) {
intersection.add(num);
}
}
System.out.println("交集:" + intersection);
}
}
將list1轉(zhuǎn)換為HashSet,以提高查找效率。然后,我們遍歷list2,并檢查其元素是否存在于set1中。如果存在,則將其添加到交集列表中。請注意,由于HashSet不保證元素的順序,因此交集列表中的元素順序可能與原始列表不同。如果需要保持順序,可以使用LinkedHashSet代替HashSet。
方法三:使用Set的retainAll方法
這種方法首先將兩個(gè)列表轉(zhuǎn)換為Set,然后利用Set的retainAll方法來找到交集。retainAll方法會(huì)保留在指定集合(參數(shù))中存在的元素。
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5); List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8); Set<Integer> set1 = new HashSet<>(list1); Set<Integer> set2 = new HashSet<>(list2); set1.retainAll(set2); // set1現(xiàn)在只包含交集元素 List<Integer> intersection = new ArrayList<>(set1);
方法四:使用Java的CollectionUtils(Apache Commons Collections)
如果你的項(xiàng)目中已經(jīng)包含了Apache Commons Collections庫,你可以使用其提供的CollectionUtils類來方便地找到交集。
import org.apache.commons.collections4.CollectionUtils; List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5); List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8); List<Integer> intersection = (List<Integer>) CollectionUtils.intersection(list1, list2);
注意:Apache Commons Collections庫中的intersection方法返回的是java.util.Collection類型,所以需要進(jìn)行類型轉(zhuǎn)換。
方法五:使用Java Stream API的anyMatch
之前已經(jīng)用filter方法展示了如何使用Stream API找交集,但其實(shí)也可以用anyMatch來實(shí)現(xiàn)類似的功能。不過,這種方法通常不是最高效的,因?yàn)樗枰獙γ總€(gè)元素進(jìn)行遍歷檢查。
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
List<Integer> intersection = list1.stream()
.filter(item -> list2.stream().anyMatch(item::equals))
.collect(Collectors.toList());
注意:這種方法的時(shí)間復(fù)雜度較高,因?yàn)閷τ?code>list1中的每個(gè)元素,它都會(huì)遍歷整個(gè)list2。因此,對于大型列表,這種方法不推薦使用。
方法六:使用Java 8的并行流(Parallel Streams)
如果列表很大,并且你的機(jī)器有多個(gè)處理器核心,你可以考慮使用并行流來加速交集的計(jì)算。
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
Set<Integer> set2 = new HashSet<>(list2); // 使用HashSet提高查找效率
List<Integer> intersection = list1.parallelStream()
.filter(set2::contains)
.collect(Collectors.toList());
注意:并行流并不總是比順序流更快,特別是在處理小數(shù)據(jù)集或數(shù)據(jù)集不適合并行處理時(shí)。此外,并行流的使用也會(huì)增加線程的開銷。
方法七:使用Java的并發(fā)工具類
如果你在處理非常大的數(shù)據(jù)集,并且希望利用多核處理器的能力,你可以考慮使用Java的并發(fā)工具類,如ForkJoinPool,來并行計(jì)算交集。
這種方法比較復(fù)雜,通常用于高級(jí)并發(fā)編程場景?;舅悸肥菍⒋笕蝿?wù)拆分成小任務(wù),然后使用ForkJoinPool來并行處理這些小任務(wù),并最終合并結(jié)果。
方法八:使用第三方庫(如Guava)
除了Apache Commons Collections,還有其他第三方庫如Guava也提供了集合操作的工具類。
例如,使用Guava的Sets.intersection(Set<E> set1, Set<E> set2)方法可以很容易地找到兩個(gè)集合的交集:
import com.google.common.collect.Sets; List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5); List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8); Set<Integer> set1 = new HashSet<>(list1); Set<Integer> set2 = new HashSet<>(list2); Set<Integer> intersectionSet = Sets.intersection(set1, set2); List<Integer> intersection = new ArrayList<>(intersectionSet);
注意:Guava的Sets.intersection方法返回的是一個(gè)不可修改的視圖,它表示兩個(gè)原始集合的交集。這個(gè)視圖會(huì)隨著原始集合的變化而變化,但它本身不占用額外的空間。如果你需要一個(gè)獨(dú)立的交集集合,可以像上面那樣將其復(fù)制到一個(gè)新的ArrayList中。
通過以上方法的介紹和實(shí)踐,希望能夠幫助你更好地理解Java中List集合交集的計(jì)算,并能夠在實(shí)際開發(fā)中靈活運(yùn)用。
附:Java兩個(gè)較大的List快速取交集
public static void main(String[] args) {
//模擬數(shù)據(jù)
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
for (int i = 1; i <= 1000000; i++) {
list1.add(i);
list2.add(1000000 - i);
}
//記錄開始時(shí)間
long startTime = System.currentTimeMillis();
//最后結(jié)果集
List<Integer> resultList = new ArrayList<>();
//中間存儲(chǔ)
Map<String, Integer> map = new HashMap<>();
list2.forEach(i2 -> {
map.put(i2 + "", i2);
});
list1.forEach(i1 -> {
Integer m = map.get(i1 + "");
//如果不為空,則證明list1和list2都擁有該數(shù)據(jù)
if (m != null) {
resultList.add(i1);
}
});
System.out.println("耗時(shí):" + (System.currentTimeMillis() - startTime) + "ms");
System.out.println(resultList.size());
} 運(yùn)行結(jié)果

總結(jié)
到此這篇關(guān)于Java List集合取交集的8種不同實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java List集合取交集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Jenkins+Maven+Gitea+Nexus搭建CICD環(huán)境的方式
這篇文章主要介紹了基于Jenkins+Maven+Gitea+Nexus從0到1搭建CICD環(huán)境,大家都知道Nexus是一套“開箱即用”的系統(tǒng)不需要數(shù)據(jù)庫,它使用文件系統(tǒng)加Lucene來組織數(shù)據(jù),需要的朋友可以參考下2022-01-01
spring boot+jwt實(shí)現(xiàn)api的token認(rèn)證詳解
這篇文章主要給大家介紹了關(guān)于spring boot+jwt實(shí)現(xiàn)api的token認(rèn)證的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一學(xué)習(xí)學(xué)習(xí)吧2018-12-12
spring boot 自定義starter的實(shí)現(xiàn)教程
下面小編就為大家分享一篇spring boot 自定義starter的實(shí)現(xiàn)教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
基于Java?SpringBoot的前后端分離信息管理系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)
當(dāng)今社會(huì),人才的流動(dòng)速度大大增加,因此也對黨建工作的管理層面工作帶來了空前且復(fù)雜的挑戰(zhàn),從而使得如何高效的開展管理黨建工作成為了亟待解決的問題。本文將介紹通過Java?SpringBoot實(shí)現(xiàn)前后端分離信息管理系統(tǒng),感興趣的同學(xué)可以了解一下2021-11-11
Java選擇結(jié)構(gòu)與循環(huán)結(jié)構(gòu)的使用詳解
循環(huán)結(jié)構(gòu)是指在程序中需要反復(fù)執(zhí)行某個(gè)功能而設(shè)置的一種程序結(jié)構(gòu)。它由循環(huán)體中的條件,判斷繼續(xù)執(zhí)行某個(gè)功能還是退出循環(huán),選擇結(jié)構(gòu)用于判斷給定的條件,根據(jù)判斷的結(jié)果判斷某些條件,根據(jù)判斷的結(jié)果來控制程序的流程2022-03-03
Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉(zhuǎn)換為LocalDateTime出現(xiàn)的問題
這篇文章主要介紹了Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉(zhuǎn)換為LocalDateTime出現(xiàn)的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09

