从 arrayRange中删除重复的行对象列表,但在不同的列中具有重复的行项目



我有一个类型的对象

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 是列表中添加两次的同一对夫妇,只是他们的名字在列中交换。(假设在这种情况下不存在两个同名的人,约翰只提到"约翰和艾米"夫妇(谁能帮我解决这个问题?

你可以

  1. 重写equals()方法以根据需要比较对象。然后

    relationshipList.stream().distinct().collect(Collectors.asList());
    
  2. 创建一个自定义筛选器类,该类包含遇到的值的映射。然后

    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类中的equalshashCode提供实现。

要确定相等性,您需要验证大约两种状态(如果对象实际上是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())

最新更新