Java?List集合取交集的8種不同實現方式總結
方法一:使用Java 8的Stream API
這種方法利用Stream API的filter和collect操作來找到兩個列表的交集。
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());
方法二:使用傳統的for循環(huá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
轉換為HashSet
,以提高查找效率。然后,我們遍歷list2
,并檢查其元素是否存在于set1
中。如果存在,則將其添加到交集列表中。請注意,由于HashSet
不保證元素的順序,因此交集列表中的元素順序可能與原始列表不同。如果需要保持順序,可以使用LinkedHashSet
代替HashSet
。
方法三:使用Set的retainAll方法
這種方法首先將兩個列表轉換為Set,然后利用Set的retainAll方法來找到交集。retainAll方法會保留在指定集合(參數)中存在的元素。
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現在只包含交集元素 List<Integer> intersection = new ArrayList<>(set1);
方法四:使用Java的CollectionUtils(Apache Commons Collections)
如果你的項目中已經包含了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
類型,所以需要進行類型轉換。
方法五:使用Java Stream API的anyMatch
之前已經用filter
方法展示了如何使用Stream API找交集,但其實也可以用anyMatch
來實現類似的功能。不過,這種方法通常不是最高效的,因為它需要對每個元素進行遍歷檢查。
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());
注意:這種方法的時間復雜度較高,因為對于list1
中的每個元素,它都會遍歷整個list2
。因此,對于大型列表,這種方法不推薦使用。
方法六:使用Java 8的并行流(Parallel Streams)
如果列表很大,并且你的機器有多個處理器核心,你可以考慮使用并行流來加速交集的計算。
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());
注意:并行流并不總是比順序流更快,特別是在處理小數據集或數據集不適合并行處理時。此外,并行流的使用也會增加線程的開銷。
方法七:使用Java的并發(fā)工具類
如果你在處理非常大的數據集,并且希望利用多核處理器的能力,你可以考慮使用Java的并發(fā)工具類,如ForkJoinPool
,來并行計算交集。
這種方法比較復雜,通常用于高級并發(fā)編程場景?;舅悸肥菍⒋笕蝿詹鸱殖尚∪蝿?,然后使用ForkJoinPool
來并行處理這些小任務,并最終合并結果。
方法八:使用第三方庫(如Guava)
除了Apache Commons Collections,還有其他第三方庫如Guava也提供了集合操作的工具類。
例如,使用Guava的Sets.intersection(Set<E> set1, Set<E> set2)
方法可以很容易地找到兩個集合的交集:
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
方法返回的是一個不可修改的視圖,它表示兩個原始集合的交集。這個視圖會隨著原始集合的變化而變化,但它本身不占用額外的空間。如果你需要一個獨立的交集集合,可以像上面那樣將其復制到一個新的ArrayList中。
通過以上方法的介紹和實踐,希望能夠幫助你更好地理解Java中List集合交集的計算,并能夠在實際開發(fā)中靈活運用。
附:Java兩個較大的List快速取交集
public static void main(String[] args) { //模擬數據 List<Integer> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); for (int i = 1; i <= 1000000; i++) { list1.add(i); list2.add(1000000 - i); } //記錄開始時間 long startTime = System.currentTimeMillis(); //最后結果集 List<Integer> resultList = new ArrayList<>(); //中間存儲 Map<String, Integer> map = new HashMap<>(); list2.forEach(i2 -> { map.put(i2 + "", i2); }); list1.forEach(i1 -> { Integer m = map.get(i1 + ""); //如果不為空,則證明list1和list2都擁有該數據 if (m != null) { resultList.add(i1); } }); System.out.println("耗時:" + (System.currentTimeMillis() - startTime) + "ms"); System.out.println(resultList.size()); }
運行結果
總結
到此這篇關于Java List集合取交集的8種不同實現方式的文章就介紹到這了,更多相關Java List集合取交集內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Jenkins+Maven+Gitea+Nexus搭建CICD環(huán)境的方式
這篇文章主要介紹了基于Jenkins+Maven+Gitea+Nexus從0到1搭建CICD環(huán)境,大家都知道Nexus是一套“開箱即用”的系統不需要數據庫,它使用文件系統加Lucene來組織數據,需要的朋友可以參考下2022-01-01spring boot+jwt實現api的token認證詳解
這篇文章主要給大家介紹了關于spring boot+jwt實現api的token認證的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一學習學習吧2018-12-12基于Java?SpringBoot的前后端分離信息管理系統的設計和實現
當今社會,人才的流動速度大大增加,因此也對黨建工作的管理層面工作帶來了空前且復雜的挑戰(zhàn),從而使得如何高效的開展管理黨建工作成為了亟待解決的問題。本文將介紹通過Java?SpringBoot實現前后端分離信息管理系統,感興趣的同學可以了解一下2021-11-11Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉換為LocalDateTime出現的問題
這篇文章主要介紹了Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉換為LocalDateTime出現的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09