2016-06-14 91 views
0

我希望用TreeSet根据其属性(这里是toString()其返回对象的名称),删除重复的对象,这里是我的代码:的Java TreeSet中删除重复的基于对象的属性

Set<Object> s = new TreeSet<>(new Comparator<Object>() {   
      @Override 
      public int compare(Object o1, Object o2) { 
       if (o1.toString().equals(o2.toString())) { 
        return 0; 
       } else { 
        return 1; 
       } 
      } 
     }); 
s.addAll(listComCopy); 
listComCopy.clear(); 
listComCopy.addAll(s); 

listComCopy是一个列表对象。

它做的工作,但它只比较列表上的连续对象,所以如果我有list(50).equals(list(150))它会忽略。

你有什么想法,我该如何重构此代码,以消除所有重复无regardeless他们在列表中的顺序?

+1

在Java 8中,您可以使用'new TreeSet <>(比较器。比较(Object :: toString));' – Holger

回答

2

compare方法不符合要求。

Comparator.compare ...

比较它的两个参数的顺序。返回负整数,零或正整数作为第一个参数是小于,等于或大于第二个。

compare中使用String.compareTo会更好。

Set<Object> s = new TreeSet<>(new Comparator<Object>() { 
     @Override 
     public int compare(Object o1, Object o2) { 
      return o1.toString().compareTo(o2.toString()); 
     } 
    }); 
+0

它的工作原理!非常感谢veru! –

1

您可能想使用compareTo方法比较字符串,而不是使用equals方法。这将允许树集合构建像结构一样的实际树。

1

根据TreeSet中的构造javadoc

TreeSet的(比较比较)
构造一个新的空树集,根据指定的比较排序。

您提供的比较器仅用于排序,而不用于重复删除。

如果你想删除重复项,你应该在你的对象类上实现.equals().hashcode()这个TreeSet,所以当你向它添加一个新的元素时,重复的删除逻辑就会出现。

+0

也许你应该重新阅读链接文档,尤其是“* a'TreeSet'实例使用它的'compareTo'(或'compare')方法执行所有元素比较的部分* – Holger

+0

+1有趣的是,构造函数javadoc是误导性的,有些人可能会认为TreeSet有点违反通过不使用equals和hashcode来设置合约。对你感到羞耻,java。 – everton

+1

那么,文档说*完全*,即在顺序与'equals'不一致的情况下,'TreeSet'不服从'Set'接口的一般契约。哈希代码是不相关的,因为它不是一般'Set'合约的一部分(如果'hashCode'与'equals'不一致,你可以说'HashSet'不服从'Set'合约)... – Holger

1

您应该重新考虑您Comparator的实施。从java.util.Comparator#compare的Javadoc:

@返回负整数,零,或作为 *第一个参数的正整数比 *第二小于,等于,或更大。

你永远不会在你的代码返回负数,考虑return o1.toString().compareTo(o2.toString())为您Comparator实现