Intersection of Two Lists in Java – Java中两个列表的交集

最后修改: 2018年 12月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll learn how to retrieve the intersection of two Lists.

在本教程中,我们将学习如何检索两个Lists的交集

Like many other things, this has become much easier thanks to the introduction of streams in Java 8.

与其他许多事情一样,由于在Java 8中引入了streams,这已经变得非常容易。

2. Intersection of Two Lists of Strings

2.两个字符串列表的交集

Let’s create two Lists of Strings with some intersection — both having some duplicated elements:

让我们创建两个有一些交集的Strings的Lists–都有一些重复的元素。

List<String> list = Arrays.asList("red", "blue", "blue", "green", "red");
List<String> otherList = Arrays.asList("red", "green", "green", "yellow");

And now we’ll determine the intersection of the lists with the help of stream methods:

而现在我们将在流方法的帮助下确定列表的交集

Set<String> result = list.stream()
  .distinct()
  .filter(otherList::contains)
  .collect(Collectors.toSet());

Set<String> commonElements = new HashSet(Arrays.asList("red", "green"));

Assert.assertEquals(commonElements, result);

First, we remove the duplicated elements with distinct. Then, we use the filter to select the elements that are also contained in the otherList.

首先,我们用distinct删除重复的元素。然后,我们使用过滤器来选择那些也包含在其他列表中的元素。

Finally, we convert our output with a Collector. The intersection should contain each common element only once. The order shouldn’t matter, thus toSet is the most straightforward choice, but we can also use toList or another collector method.

最后,我们用一个Collector转换我们的输出。交集应该只包含每个共同元素一次。顺序应该不重要,因此toSet是最直接的选择,但我们也可以使用toList或其他收集器方法。

For more details, review our guide to Java 8’s Collectors.

有关详细信息,请查看我们的Java 8 的收集器指南

3. Intersection of Lists of Custom Classes

3.自定义类列表的交集

What if our Lists don’t contain Strings but rather instances of a custom class we’ve created? Well, as long as we follow Java’s conventions, the solution with stream methods will work fine for our custom class.

如果我们的Lists不包含Strings,而是包含我们所创建的自定义类的实例,该怎么办?那么,只要我们遵循Java的惯例,使用流方法的解决方案对我们的自定义类来说就可以正常工作。

How does the contains method decide whether a specific object appears in a list? Based on the equals method. Thus, we have to override the equals method and make sure that it compares two objects based on the values of the relevant properties.

contains方法如何决定一个特定对象是否出现在列表中?基于equals方法。因此,我们必须覆盖equals方法,并确保它根据相关属性的值对两个对象进行比较。

For instance, two rectangles are equal if their widths and heights are equal.

例如,如果两个矩形的宽度和高度相等,它们就是相等的。

If we don’t override the equals method, our class uses the equals implementation of the parent class. At the end of the day, or rather, the inheritance chain, the Object class’ equals method gets executed. Then two instances are equal only if they refer to exactly the same object on the heap.

如果我们不覆盖equals方法,我们的类将使用父类的equals实现。在最后,或者说,在继承链中,Object类的equals方法被执行。然后,只有当两个实例在堆上引用完全相同的对象时,它们才是相等的。

For more information about the equals method, see our article on Java equals() and hashCode() Contracts.

关于equals方法的更多信息,请参见我们关于Java equals()hashCode()合约的文章

4. Conclusion

4.结论

In this quick article, we’ve seen how to use streams to calculate the intersection of two lists. There are many other operations that used to be quite tedious but are pretty straightforward if we know our way around the Java Stream API. Take a look at our further tutorials with Java streams here.

在这篇简短的文章中,我们已经看到了如何使用流来计算两个列表的交集。还有许多其他的操作,过去是相当乏味的,但如果我们了解了Java流API的方法,就会变得非常简单。请看我们的Java流的进一步教程

Code examples are available over on GitHub.

代码示例可在GitHub上获得