【问题标题】:Java Comparator in Sets with equal items具有相等项的集合中的 Java 比较器
【发布时间】:2014-07-22 17:12:16
【问题描述】:

通常在 TreeSet 中不应该有两个相等的项。但实际上,在某些情况下,您经常想要维护一种排序的 List 而不是 Set。 Java 中仍然没有 TreeList 或任何 SortedList。虽然您当然可以使用 Collections.sort()。

我的问题是:使用 TreeSet(或任何排序集)以使其也包含相等项的正确方法是什么?

我通常会这样做:

new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        int result = Float.compare(o1.getDistance(), o2.getDistance());

        //both distances are equal so we use the object hash as distinctive
        //property.
        if (result == 0) {
            result = Integer.compare(System.identityHashCode(o1), 
                System.identityHashCode(o2))
        }
        return result;
    }
}

虽然这很有效,但它的缺点当然是仍然存在 散列冲突 的可能性很小,这会导致 TreeSet 中丢失对象 .

所以我想知道是否有更好的方法来真正正确区分这些对象?

【问题讨论】:

  • 哦,不要那样使用 TreeSet,除非你的目的是混淆其他人。
  • 您可以向 MyObject 添加一个字段,该字段对于不同的记录应该始终是唯一的。或者您可以使用 List 并对其进行排序。
  • 有时两个对象之间的唯一区别是,它们是两个不同的对象。所以当然,如果我可以添加一个唯一的 ID,我肯定会使用它。但有时这是不可能的。

标签: java set equality comparator treeset


【解决方案1】:

我一直在用

import com.google.common.collect.TreeMultiset;

轻松成功。

当有好的库存在时,您不应该尝试使用变通方法。

当然,也可能有其他库。

稍后

我应该在 "equal" 和 "set" 的组合中提出一个危险信号。这是一个禁忌。您可以在 Map 中拥有多个相等的相等键。

如果要重复存储对象,即使相等,也可以使用List;是否应添加相等元素由您决定。

另一个想法:

也许你想要一个使用引用相等而不是相等的 IdentityHashMap。

但是,如果您在课堂上违反了 hashCode/equals 约定,请为无尽的困难做好准备。

【讨论】:

  • 我刚刚测试了 TreeMultiset,它也有同样的问题。唯一的区别是它保留了两个相同的对象而不是一个。但是,如果我想拥有两个根据 Comparator 相等但仍然具有不同属性的对象,那么我会丢失其中一个对象。例如。如果我添加两个 id 为 1 的对象 A(1) 和 id 为 2 的 A(2) 并且根据 Comparator 两者都相等,则 Multiset 仅包含两次 A(1) 但 A(2) 消失了。
  • 等于等于等于。也许我应该指出...查看更新的答案,
  • 嗯...我想我发现了一个非常特殊的情况,我需要在一个排序集合中使用多个值,根据比较器可能等于但不等于 hashCode/equals。我认为解决此问题的最佳方法是 1)使用 TreeSet 并防止可能的哈希冲突或 2)编写基于红黑树的 List 实现。在大多数情况下,您的答案仍然可以完成工作,所以我接受它作为解决方案:)
【解决方案2】:
package newfeature;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;`enter code here`
class employee {
    String name;
    int idno;
    public employee(int idno, String name) {
        this.name = name;
        this.idno = idno;
    }
}
public class setcom {
    public static void main(String[] args) {
        Set<employee> emset = new HashSet<>();
        emset.add(new employee(1, "rohan"));
        emset.add(new employee(2, "sohan"));
        emset.add(new employee(3, "mohan"));
        emset.add(new employee(4, "zohan"));
        for (employee em : emset) {
            System.out.println(em.name);
        }
        Set<employee> sorted = new TreeSet<>(new Comparator<employee>() {
            @Override
            public int compare(employee o1, employee o2) {
                return o1.name.compareTo(o2.name);
            }
        });
        sorted.addAll(emset);
        System.out.println("*******separotor*******");
        for (employee em : sorted) {
            System.out.println(em.name);
        }

    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多