如何在不覆盖 equals() 和 hashCode() 的情况下,根据单个 属性 过滤两个 Set 中包含的对象

How to filter objects contained in two Sets based on a single property without overriding equals() and hashCode()

我有一个 集合 的对象,并试图通过 id 查找对象是否存在于列表中。我不想覆盖 equals()hashCode().

class ABC {
    Long id;
    String name;
}

我想在不覆盖 equals()hashCode() 方法的情况下执行以下语句

Set<ABC> abcSetOne;
Set<ABC> abcSetTwo;

abcSetOne.stream()
   .filter(abcSetTwo::contains)
   .collect(Collectors.toSet());

id保证唯一。

我正在使用 Java 8.

基于单个属性的对象相等性

当需要根据一个属性设置对象的交集(根据集合论)而不改变现有的hashCode()equals() 方法,您可以创建 HashSetids.

public static void main(String[] args) {
    Set<ABC> abcSetOne = Set.of(new ABC(1L, "first"), new ABC(2L, "second"), new ABC(3L, "third"));
    Set<ABC> abcSetTwo = Set.of(new ABC(1L, "first"), new ABC(5L, "fifth"), new ABC(3L, "third"));
    
    Set<Long> idsOne = abcSetTwo.stream()
        .map(ABC::getId)
        .collect(Collectors.toSet());
    
    Set<ABC> result = abcSetOne.stream()
        .filter(abc -> idsOne.contains(abc.getId()))
        .collect(Collectors.toSet());
    
    System.out.println(result);
}

输出

[ABC{id=1, name='first'}, ABC{id=3, name='third'}]

基于多个属性的对象相等性

当您需要基于 多个对象的 属性 建立唯一性时,您可以使用 hashCode/equals 定义包装器 class基于这些属性实现的合约。

作为包装器,您可以利用 Java 16 条记录,这将使代码更精简(hashCode()equals() 将由编译器生成)

public record ABCWrapper(Long id, String name) {
    ABCWrapper(Wrapping.ABC abc) {
        this(abc.getId(), abc.getName());
    }
}

对于早期版本,ABCWrapper 可以定义为普通的 class。

main() - 演示

public static void main(String[] args) {
    Set<ABC> abcSetOne = Set.of(new ABC(1L, "first"), new ABC(2L, "second"), new ABC(3L, "third"));
    Set<ABC> abcSetTwo = Set.of(new ABC(1L, "first"), new ABC(5L, "fifth"), new ABC(3L, "third"));
    
    Map<ABCWrapper, ABC> abcByWrapper = abcSetTwo.stream()
        .collect(Collectors.toMap(ABCWrapper::new, Function.identity()));
    
    Set<ABC> result = abcSetOne.stream()
        .map(ABCWrapper::new)
        .filter(abcByWrapper::containsKey)
        .map(abcByWrapper::get)
        .collect(Collectors.toSet());

    System.out.println(result);
}

输出

[ABC{id=1, name='first'}, ABC{id=3, name='third'}]