当前位置: 首页 > 知识库问答 >
问题:

Java流-从其他两个列表中获取“对称差异列表”

滑骞尧
2023-03-14

我正在尝试使用Java8流来组合列表。如何从两个现有列表中获得“对称差异列表”(只存在于一个列表中的所有对象)。我知道如何获取intersect列表,也知道如何获取union列表。

示例代码:

public void testDisjointLists() {
    List<Car> bigCarList = get5DefaultCars();
    List<Car> smallCarList = get3DefaultCars();

    //Get cars that exists in both lists
    List<Car> intersect = bigCarList.stream().filter(smallCarList::contains).collect(Collectors.toList());

    //Get all cars in both list as one list
    List<Car> union = Stream.concat(bigCarList.stream(), smallCarList.stream()).distinct().collect(Collectors.toList());

    //Get all cars that only exist in one list
    //List<Car> disjoint = ???

}

public List<Car> get5DefaultCars() {
    List<Car> cars = get3DefaultCars();
    cars.add(new Car("Toyota Corolla", 2008));
    cars.add(new Car("Ford Focus", 2010));
    return cars;
}

public List<Car> get3DefaultCars() {
    List<Car> cars = new ArrayList<>();
    cars.add(new Car("Volvo V70", 1990));
    cars.add(new Car("BMW I3", 1999));
    cars.add(new Car("Audi A3", 2005));
    return cars;
}

class Car {
    private int releaseYear;
    private String name;
    public Car(String name) {
        this.name = name;
    }
    public Car(String name, int releaseYear) {
        this.name = name;
        this.releaseYear = releaseYear;
    }

    //Overridden equals() and hashCode()
}

共有1个答案

孔永年
2023-03-14

基于您自己的代码,有一个简单的解决方案:

List<Car> disjoint = Stream.concat(
    bigCarList.stream().filter(c->!smallCarList.contains(c)),
    smallCarList.stream().filter(c->!bigCarList.contains(c))
).collect(Collectors.toList());

只需筛选一个列表中未包含的所有项,反之亦然,并将两个结果串联起来。这对小列表很好用,在考虑优化的解决方案(如散列或使结果distince())之前,您应该问问自己,如果您既不想要列表,也不想要重复列表,也不想要特定的顺序,那么您为什么要使用列表。

看起来您实际上想要sets,而不是lists。如果您使用setS,Tagir Valeev的解决方案是合适的。但是它不能使用list的实际语义,也就是说,如果源列表包含重复项,它就不起作用。

Set<Car> disjoint = Stream.concat(bigCarSet.stream(), smallCarSet.stream())
  .collect(Collectors.toMap(Function.identity(), t->true, (a,b)->null))
  .keySet();

collectors.tomap的文档说明,合并函数被视为“提供给map.merge(Object,Object,BiFunction)”,从这里我们可以了解到,简单地将重复对映射到null将删除条目。

因此之后,映射的keyset()包含不相交集。

 类似资料:
  • 问题内容: 我有两个清单,和。我需要的物品不在其中。 我只想得到[4,5]-l1中只有新值。 我可以不用迭代吗? 问题答案: 简短的回答,是的:,但这不会保持秩序。 长答案,不,因为在内部CPU总是会迭代。但如果你使用的是迭代将进行高度优化,并会快那么你的列表解析(更不用说检查会员是 多 快带套然后列出)。

  • 我有一个名为Trade的实体,它可以映射到包含属性的表。这个实体也有一个字段,存储来自另一个表的值。我的贸易表包含第二个表的主键。我知道如何获得整个第二个表作为实体在我的贸易实体,但我只想要1列。 如你所见,我尝试了,但是连接是在贸易实体的主密钥上执行的。我如何使用注释从贸易表中选择外键,将其连接到第二/第三表,并直接只从col2/col3中获取值?任何建议都很感激 餐桌贸易: 表2: 表3: 现

  • 我有一个带有Person对象的数据库表。我的网络服务接收一个Person对象列表来更新这个Person表。我的应用程序现在包含两个列表: 我想遍历这些列表,并创建一个新列表,用于更新Person表。 fName和lName用于识别现有记录。下面是一个例子。 现在的 乔,布洛格斯,18岁,joe@me.com 简,布洛格斯,21岁,jane@me.com 弗洛,布洛格斯,25岁,flo@me.com

  • 问题内容: 我正在尝试创建一个包含2个列表并返回仅具有两个列表差异的列表的函数。 例: 结果应打印 到目前为止的功能: 第一个for循环将其排序,第二个将重复项删除。问题是结果 不是,所以不能完全删除重复项吗?我可以添加些什么来做到这一点。我不能使用任何特殊模块,.sort,set或其他任何东西,而只是基本地循环。 问题答案: 基本上,您希望将一个元素添加到新列表中(如果一个元素存在而另一个元素中

  • 问题内容: 我在Python中有两个列表,如下所示: 我需要用第一个列表中的项目创建第二个列表,而第二个列表中没有这些项目。从示例中,我必须得到: 有没有循环和检查的快速方法吗? 问题答案: 当心 你可能期望/希望它等于的位置。如果你想作为答案,则需要使用