Java中计算多维ArrayList差值:获取B中不存在于A的元素
解决思路:找出B中不存在于A中的元素
核心问题在于:你的ArrayList中存储的是子列表/数组,而Java中默认的contains或removeAll方法对于数组是比较引用而非内容;如果是List类型,虽然equals会比较内容,但要确保你用的是正确的List实现。下面分两种情况给出具体解决方案:
情况1:你的集合是List<List<String>>(存储的是List而非数组)
如果A和B都是List<List<String>>类型,直接利用List.equals()的特性(会逐一比较子列表中的元素内容),用Stream API就能快速解决:
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class ListComparison { public static void main(String[] args) { // 初始化列表A(修正了拼写,和B的第一个元素匹配,否则预期结果会包含该元素) List<List<String>> listA = new ArrayList<>(); listA.add(List.of("lgi09", "Verantwortlicher")); listA.add(List.of("mne09", "Developer")); listA.add(List.of("root", "Verantwortlicher")); // 初始化列表B List<List<String>> listB = new ArrayList<>(); listB.add(List.of("lgi09", "Verantwortlicher")); listB.add(List.of("lgi09", "Developer")); listB.add(List.of("ltr09", "Bereitschafter")); listB.add(List.of("fmo09", "Bereitschafter")); // 过滤出B中不在A里的元素 List<List<String>> result = listB.stream() .filter(element -> !listA.contains(element)) .collect(Collectors.toList()); // 验证结果 System.out.println(result); // 输出:[[lgi09, Developer], [ltr09, Bereitschafter], [fmo09, Bereitschafter]] } }
为什么这个方法有效?
List.of()返回的不可变列表,以及普通ArrayList的equals方法,都会逐一比较子列表中的每个元素,所以listA.contains(element)能准确判断子列表是否在A中存在。
情况2:你的集合是List<String[]>(存储的是字符串数组)
如果A和B存储的是String[]数组,默认的contains方法会比较数组的引用而非内容,这时候需要用Arrays.equals()来手动比较数组内容:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class ArrayComparison { public static void main(String[] args) { // 初始化数组列表A List<String[]> listA = new ArrayList<>(); listA.add(new String[]{"lgi09", "Verantwortlicher"}); listA.add(new String[]{"mne09", "Developer"}); listA.add(new String[]{"root", "Verantwortlicher"}); // 初始化数组列表B List<String[]> listB = new ArrayList<>(); listB.add(new String[]{"lgi09", "Verantwortlicher"}); listB.add(new String[]{"lgi09", "Developer"}); listB.add(new String[]{"ltr09", "Bereitschafter"}); listB.add(new String[]{"fmo09", "Bereitschafter"}); // 过滤出B中不在A里的元素 List<String[]> result = listB.stream() .filter(bArr -> !listA.stream().anyMatch(aArr -> Arrays.equals(aArr, bArr))) .collect(Collectors.toList()); // 验证结果 result.forEach(arr -> System.out.println(Arrays.toString(arr))); // 输出: // [lgi09, Developer] // [ltr09, Bereitschafter] // [fmo09, Bereitschafter] } }
如果你不习惯用Stream,也可以用传统循环:
List<String[]> result = new ArrayList<>(); for (String[] bArr : listB) { boolean existsInA = false; for (String[] aArr : listA) { if (Arrays.equals(aArr, bArr)) { existsInA = true; break; } } if (!existsInA) { result.add(bArr); } }
你之前可能踩的坑
如果之前直接用listB.removeAll(listA)或者!listA.contains(bElement)却没得到预期结果,大概率是因为:
- 存储的是数组时,默认的
equals比较的是数组引用,而非内容; - 存储的是List时,可能不小心用了自定义的列表实现,或者子列表的元素有拼写差异(比如你A中的
Verantworlichter少了一个t,和B中的Verantwortlicher不匹配,这时候这个元素会被纳入结果,但你的预期结果里没有,所以应该是拼写笔误)。
内容的提问来源于stack exchange,提问作者Gabsii
相关产品推荐
相关产品推荐

