Java - 如何在没有 TreeSet 的情况下比较自定义等于/比较器上的 2 个集合?

问题描述

所以我有 2 个汽车列表

(伪代码

Class car
private String make
private String model
private Set<String> addons
List<Car> carsmine = ... 
List<Car> carsDealers = ...

目前,我想根据不同的标准找出这两个列表之间的差异

例如,如果我想在 carsmine 中查找与 make 中的汽车具有相同 addonscarsDealers 的所有汽车。

目前,我正在做

class MyComparator<Car> implements Comparator<Car> {
  public int compare(Car a,Car b) {
    result = a.make.compareto(b.make)
    if (result == 0) {
       if (a.addons.size() != b.addons.size()) {
          return -1
       }
       if (!a.addons.containsAll(b.addons)) {
          return -1
       }
     return result
  }
}

TreeSet<Car> carsmineTreeSet = new TreeSet<Car>(new MyComparator<Car>);
carsmineTreeSet.addAll(carsmine)
TreeSet<Car> carsDealerTreeSet = new TreeSet<Car>(new MyComparator<Car>);
carsDealerTreeSet.addAll(carsDealers)

carsmineTreeSet.retainAll(carsDealerTreeSet);

List<Car> carsWithSameMakeAndAddons = new ArrayList<Car>(carsmineTreeSet);

由于我在各种其他条件下执行此操作,因此我正在创建自定义比较器并重复此操作。

  1. 有没有办法用 HashSet 来做到这一点,因为它们是 O(1)?我无法覆盖 Equals,因为我在不同的条件集上多次执行此操作
  2. 有没有更好的方法来做到这一点?

解决方法

如果我想在carsMine中找到与carsDealers中的汽车具有相同品牌和插件的所有汽车。

这似乎不适用于 TreeSet 和提到的 MyComparator

例如汽车列表如下:

List<Car> mine = Arrays.asList(
    new Car("BMW","X5",Set.of("a","b","c")),new Car("BMW","X6",new Car("Opel","Astra",Set.of("a"))
    
);

List<Car> dealers = Arrays.asList(
    new Car("BMW",new Car("Audi","Q7","i8","c"))
    
);

然后在使用忽略 TreeSet 字段的比较器转换为 model 时,集合“丢失”了一辆 BMW 汽车。

TreeSet<Car> carsMineTreeSet = new TreeSet<Car>(new MyComparator());
carsMineTreeSet.addAll(mine);
System.out.println("treeset: mine: " +  carsMineTreeSet);
///////////
treeset: mine: [{make=BMW model=X5 addons=[c,b,a]},{make=Opel model=Astra addons=[a]}]

因此无法达到找到所有匹配makeaddons的汽车的最初目的。

这可以通过在经销商列表中建立一组“密钥”,然后过滤另一个列表来解决:

Set<String> keys = dealers.stream()
                          .map(c -> c.make + c.addons)
                          .collect(Collectors.toSet());

List<Car> cars = mine.stream()
    .filter(c -> keys.contains(c.make + c.addons))
    .collect(Collectors.toList());
System.out.println(cars);

输出:

[{make=BMW model=X5 addons=[c,a,b]},{make=BMW model=X6 addons=[c,b]}]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...