Java 从对象的arrayList中删除重复的行,但在不同的列中包含重复的行项目

Java 从对象的arrayList中删除重复的行,但在不同的列中包含重复的行项目,java,arraylist,Java,Arraylist,我有一个类型的对象 对(字符串person1,字符串person2) 和一个ArrayList relationshipList=new ArrayList()具有耦合类型的各种项,其中所有耦合对象在列表中复制一次。 例如,这是我的示例arrayList: relationshipList.add(new Couple("John", "Amy")); relationshipList.add(new Couple("Eliot", "Megan")); relationshipList.add

我有一个类型的对象

对(字符串person1,字符串person2)

和一个
ArrayList relationshipList=new ArrayList()具有耦合类型的各种项,其中所有耦合对象在列表中复制一次。
例如,这是我的示例arrayList:

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是同一对夫妇,在列表中添加了两次,在列中只交换了他们的名字。(假设在这个场景中不存在两个同名的人,John只提到“John和Amy”夫妇),有人能帮我吗

你可以

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

    relationshipList.stream().distinct().collect(Collectors.asList());
    
  • 创建一个自定义筛选器类,它保存遇到的值的映射。然后

    relationshipList.stream().filter(yourFilter::compare).collect(Collectors.asList());
    

  • 您首先需要为下面的夫妇实现equals方法

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

    然后,您可以将每一对添加到
    集合中
    所有重复项都将被删除。

    基本问题是重复项,只有一个数据结构可以保证删除重复项:集合

    为了利用集合,您必须为
    类中的
    equals
    hashCode
    提供实现

    要确定相等性,您需要验证大约两种状态(如果对象实际上是一对
    对象,则不包括这两种状态):

    • 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,并且您愿意添加一个实用程序方法,可以从以下位置获取:

    公共静态谓词distinctByKey(函数键提取器){
    Set seen=ConcurrentHashMap.newKeySet();
    返回t->seen.add(keydextractor.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())
    
    relationshipList.stream()
    .map(x->new SimpleEntry(x,
    Stream.of(x.getPerson1(),x.getPerson2()).sorted().collect(collector.joining()))
    .filter(distinctByKey(条目::getValue))
    .map(条目::getKey)
    .collect(收集器.toList())
    
    在add语句中的所有字符串前面是否有一对隐式的
    新人(
    )?最初,是的,我有他们。我试图保持它的简短,所以添加了一个示例列表。这就是我真正的做法:
    私有void saveRelationshipList(String firstPerson,String secondPerson,String relationshipValue)引发异常{relationshipList.add(新的家庭关系(第一人称、第二人称、relationshipValue));}
    你能改变你的
    类吗?添加equals/hashCode?可能是@Imaskar的重复,他说OP搜索lambda方法?是的,我同意。但我无法理解循环将如何进行,因为我无法在迭代时从列表中删除对象。假设我比较第一个项目(我的第一个循环),即“john and amy”并通过另一个循环迭代找到“amy and john”,然后我会找到他们一次,但在我的第四次迭代中找到我的“amy and john”"将作为第二个循环中的第一项再次被发现。它不断变得多余。我可能遗漏了一些非常愚蠢的东西,但我真的被困在这里。为什么要筛选?看不到它在哪里被askedDon'r delete,你将有一个新列表,结果只有不同的值。如果不需要,你可以丢弃原始列表。你不需要我想我必须重写equals/hashCode…@Eugene:现在编写一个测试,并等待
    Person
    添加更多字段。点完全有效,不能完全同意,但有时你不能重写hashCode/equals-这是我的主要问题point@Eugene:鉴于OP似乎完全控制着该对象,我认为该操作无效假设他们不能推翻这些方法。我会在OP确认后立即投票,或者你可以提供适当的证据
    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())