如何在不覆盖 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()
方法,您可以创建 HashSet
个 id
s.
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'}]
我有一个 集合 的对象,并试图通过 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()
方法,您可以创建 HashSet
个 id
s.
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'}]