簡體   English   中英

Java - 如何在沒有 TreeSet 的自定義等於/比較器上比較 2 個集合?

[英]Java - How can I compare 2 sets on a custom equals/comparator without TreeSet?

所以我有2個汽車清單

(偽代碼)

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

目前,我想根據不同的標准找到這兩個列表之間的差異

例如,如果我想在carsDealers中查找與carsMine中的汽車具有相同makeaddons的所有汽車。

目前,我正在做

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. 有沒有辦法用 HashSets 做到這一點,因為它們是 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", Set.of("a", "b", "c")),
    new Car("Opel", "Astra", Set.of("a"))
    
);

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

然后在使用忽略model字段的比較器轉換為TreeSet時,該集合“丟失”了一輛寶馬汽車。

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);

Output:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM