我有一个类型的对象
Couple(String person1, String person2)
,
以及具有各种 Couple 类型的项的ArrayList<Couple> relationshipList = new ArrayList<Couple>();
,其中所有 Couple 对象在列表中重复一次。 例如,这是我的示例数组列表:
relationshipList.add(new Couple("John", "Amy"));
relationshipList.add(new Couple("Eliot", "Megan"));
relationshipList.add(new Couple("Billy", "Rachel"));
relationshipList.add(new Couple("Amy", "John"));
relationshipList.add(new Couple("Jim", "Kate"));
relationshipList.add(new Couple("Kate", "Jim"));
relationshipList.add(new Couple("Megan", "Eliot"));
relationshipList.add(new Couple("Rachel", "Billy"));
我正在尝试找到一种方法来删除重复的夫妇,因为在本例中,John 和 Amy 是列表中添加两次的同一对夫妇,只是他们的名字在列中交换。(假设在这种情况下不存在两个同名的人,约翰只提到"约翰和艾米"夫妇(谁能帮我解决这个问题?
你可以
-
重写
equals()
方法以根据需要比较对象。然后relationshipList.stream().distinct().collect(Collectors.asList());
-
创建一个自定义筛选器类,该类包含遇到的值的映射。然后
relationshipList.stream().filter(yourFilter::compare).collect(Collectors.asList());
你首先需要为夫妇实现等于方法,如下所示
PS:你也可以把空检查
public boolean equals(Object otherCouple){
if(otherCouple != null && otherCouple instanceof Couple){
return (this.person1.equals(otherCouple.getPerson1())
&& this.person2.equals(otherCouple.getPerson2()))
|| (this.person1.equals(otherCouple.getPerson2())
&& this.person2.equals(otherCouple.getPerson1()))
}
return false;
}
然后,您只需将每对夫妇添加到Set<Couple>
所有重复项都将被删除。
根本问题是重复,只有一种数据结构可以保证删除重复项:集合。
为了利用集合,您必须为Couple
类中的equals
和hashCode
提供实现。
要确定相等性,您需要验证大约两种状态(如果对象实际上是Couple
则除外(:
this.person1 == other.person1 && this.person2 == other.person2
this.person2 == other.person1 && this.person1 == other.person2
你会把这些表达为Objects.equals(this.person1, other.person1) && Objects.equals(this.person2, other.person2)
,但完整的写作对读者来说是一种练习。
至于哈希代码,您可以使用Objects.hashCode
为您获取该值。
@Override
public int hashCode() {
return Objects.hashCode(person1, person2);
}
如果你不能覆盖equals/hashCode,并且你愿意使用java-8,并且你愿意添加一个实用程序方法,取自Stuart Mark的答案:
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
这可以通过以下方式完成:
relationshipList.stream()
.map(x -> new SimpleEntry<>(x,
Stream.of(x.getPerson1(), x.getPerson2()).sorted().collect(Collectors.joining())))
.filter(distinctByKey(Entry::getValue))
.map(Entry::getKey)
.collect(Collectors.toList())