两个List的交集,补集

用linq是很好实现的

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleProgram { class Program { static void Main(string[] args) { var oneList = new List<int>(); var twoList = new List<int>(); oneList.Add(1); oneList.Add(2); oneList.Add(3); twoList.Add(1); twoList.Add(2); twoList.Add(3); twoList.Add(4); //where (from o in oneList select o).Contains(i) 包含 //where !(from o in oneList select o).Contains(i) 不包含 var searchResult = from i in twoList where !(from o in oneList select o).Contains(i) select i; //打印到屏幕 foreach (int num in searchResult) { Console.Write(num); } Console.Read(); } } }

<think> 我们参考了多个引用来源,其中提到在Java中求两个List交集主要有以下几种方法: 1. 使用List的`retainAll`方法:该方法会修改调用它的List,使其只保留与另一个List共有的元素(即交集)。注意:该方法会改变原始List,如果不希望改变原始List,可以先创建副本。 2. 使用Stream API:利用Java 8的Stream,通过`filter`和`contains`来筛选出共有的元素,然后收到新的List中。这种方法不会改变原始List。 3. 使用传统的循环遍历:手动遍历一个List,并检查元素是否存在于另一个List中,将共有的元素添加到新的List中。 下面我们将分别展示这三种方法的代码示例。 ### 方法一:使用`retainAll`方法 ```java import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ListIntersection { public static void main(String[] args) { // 创建两个List List<String> list1 = new ArrayList<>(Arrays.asList("a", "b", "c")); List<String> list2 = new ArrayList<>(Arrays.asList("b", "c", "d")); // 使用retainAll求交集(会改变list1) list1.retainAll(list2); System.out.println("交集: " + list1); // 输出: [b, c] } } ``` 注意:`retainAll`会修改`list1`,使其成为两个List交集。如果不想改变原始List,可以先复制一份: ```java List<String> intersection = new ArrayList<>(list1); intersection.retainAll(list2); ``` ### 方法二:使用Stream API(推荐,不改变原始List) ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class ListIntersection { public static void main(String[] args) { List<String> list1 = Arrays.asList("a", "b", "c"); List<String> list2 = Arrays.asList("b", "c", "d"); List<String> intersection = list1.stream() .filter(list2::contains) .collect(Collectors.toList()); System.out.println("交集: " + intersection); // 输出: [b, c] } } ``` ### 方法三:使用循环遍历 ```java import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ListIntersection { public static void main(String[] args) { List<String> list1 = Arrays.asList("a", "b", "c"); List<String> list2 = Arrays.asList("b", "c", "d"); List<String> intersection = new ArrayList<>(); for (String s : list1) { if (list2.contains(s)) { intersection.add(s); } } System.out.println("交集: " + intersection); // 输出: [b, c] } } ``` ### 注意事项 1. 当List中元素数量较大时,使用`list2.contains(s)`可能会比较慢(如果list2是ArrayList,则每次contains是O(n)的复杂度,整体O(n^2))。可以考虑先将一个List转为HashSet,利用HashSet的O(1)查找来优化: ```java Set<String> set = new HashSet<>(list2); List<String> intersection = list1.stream() .filter(set::contains) .collect(Collectors.toList()); ``` 或者使用循环遍历时: ```java Set<String> set = new HashSet<>(list2); List<String> intersection = new ArrayList<>(); for (String s : list1) { if (set.contains(s)) { intersection.add(s); } } ``` 这样可以将时间复杂度从O(n^2)降低到O(n)。 2. 如果List中的元素是自定义对象,需要确保该对象正确重写了`equals`和`hashCode`方法,以便`contains`和`retainAll`等方法能正确比较对象。 3. 使用`retainAll`方法时,注意它会改变调用它的List。如果不想改变原List,请先复制。 ### 总结 在Java中求两个List交集,推荐使用Stream API结合HashSet的方式,既不会改变原始List,又能保证效率。如果数据量不大,也可以选择简单的方法。 §§相关问题§§ 1. 如何求两个List的并? 2. 如何求两个List的差List1有而List2没有的元素)? 3. 在Java中,如何判断两个List是否相等(忽略顺序)? 4. 当List中存储的是自定义对象时,求交集需要注意什么? </think> ### Java中求两个List交集的方法 在Java中,求两个List合的交集有以下几种常用方法: #### 1. 使用`retainAll()`方法(直接修改原始List) ```java List<String> list1 = new ArrayList<>(Arrays.asList("a", "b", "c")); List<String> list2 = new ArrayList<>(Arrays.asList("b", "c", "d")); list1.retainAll(list2); // 直接修改list1 System.out.println("交集: " + list1); // 输出: [b, c] ``` **注意**:此方法会**直接修改原始list1**,使其仅保留交集元素[^2][^5]。 #### 2. 使用Stream API(推荐,不改变原List) ```java List<String> list1 = Arrays.asList("a", "b", "c"); List<String> list2 = Arrays.asList("b", "c", "d"); List<String> intersection = list1.stream() .filter(list2::contains) .collect(Collectors.toList()); System.out.println("交集: " + intersection); // 输出: [b, c] ``` **优点**:不会修改原始List,适合函数式编程[^3][^4]。 #### 3. 使用HashSet优化性能(大数据量推荐) ```java Set<String> set = new HashSet<>(list2); List<String> intersection = list1.stream() .filter(set::contains) .collect(Collectors.toList()); ``` **优势**:将时间复杂度从$O(n^2)$优化到$O(n)$,尤其适合大型List[^3]。 #### 4. 手动遍历实现 ```java List<String> intersection = new ArrayList<>(); for (String item : list1) { if (list2.contains(item)) { intersection.add(item); } } ``` ### 注意事项 1. **对象相等性**:自定义对象需正确重写`equals()`和`hashCode()`方法 2. **空值处理**:List中包含`null`时需特殊处理 3. **去重需求**:结果需要去重时使用`Set` 4. **性能考量**:大数据优先选择HashSet方案 ### 完整示例 ```java import java.util.*; import java.util.stream.*; public class ListIntersection { public static void main(String[] args) { List<String> list1 = Arrays.asList("Java", "Python", "C++", null); List<String> list2 = Arrays.asList("Python", "JavaScript", "Java"); // 方法1:Stream API(过滤null) List<String> result = list1.stream() .filter(Objects::nonNull) .filter(list2::contains) .collect(Collectors.toList()); System.out.println("交集: " + result); // [Java, Python] // 方法2:HashSet优化 Set<String> set = new HashSet<>(list2); List<String> result2 = list1.stream() .filter(Objects::nonNull) .filter(set::contains) .distinct() // 去重 .collect(Collectors.toList()); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值