1

我正在寻找可以根据其键和比较器进行排序的 Map 实现。

我知道这TreeMap是要走的路,但我有一个很大的问题:比较器没有很好地定义(我知道这是一个错误,但我目前无法修复它)即使对于不是的键它也返回 0相等(就 equals() 方法而言)。

如果比较器返回 0 并且不考虑对象的 hashCode 或 equals 方法,则 TreeMap 实现假定对象相等(并因此覆盖值)。这是记录在案的,并且在大多数情况下是所需的行为。您可以通过查看 TreeMap.put() 方法来检查实现是否基于比较器,该方法包含以下片段:

        do {
            parent = t;
            cmp = cpr.compare(key, t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);

此代码遍历树,如果它在树中找到一个节点(使用比较器cpr)与应该插入的节点( )相等key,则该值将被覆盖。

但是:我正在寻找 Map 接口的实现,它基于 Comparator 进行排序,但不使用它来检测哪些是相等的。

4

4 回答 4

2

I doubt you will find a Map that does that, since it goes against the recommendation of the Comparator interface.

The ordering imposed by a comparator c on a set of elements S is said to be consistent with equals if and only if c.compare(e1, e2)==0 has the same boolean value as e1.equals(e2) for every e1 and e2 in S.

Caution should be exercised when using a comparator capable of imposing an ordering inconsistent with equals to order a sorted set (or sorted map). Suppose a sorted set (or sorted map) with an explicit comparator c is used with elements (or keys) drawn from a set S. If the ordering imposed by c on S is inconsistent with equals, the sorted set (or sorted map) will behave "strangely." In particular the sorted set (or sorted map) will violate the general contract for set (or map), which is defined in terms of equals.

You can always decorate the comparator with your own comparator like so new MyComparator(faultyComparator);

When you deletegate the calls to the faulty comparator, check its return value. If it is 0, make sure the equals() contract of the objects agree. If they don't, rectify the return value. An even better solution is to rewrite the comparator correctly and use a TreeMap, if that option is open.

于 2013-04-10T08:14:06.920 回答
0

在您的情况下,TreeMap 应该没问题。但是,听起来您没有使用 Strings 或 Wrapper 类对象作为键。如果使用自己的类对象作为键,则必须实现 hashcode() 和 equals() 方法。

于 2013-04-10T08:05:37.587 回答
0

只需实现一个永远不会返回 0 的 Comparator 并使用常规 TreeMap。

于 2013-04-10T08:10:11.683 回答
0

这将是更多的内务管理,但在我看来,您需要某种两级结构,TreeMap<K, LinkedHashMap<K, V>>其中外部映射基于您的“错误”比较器,其值是正常的等值感知映射(其键将全部是根据比较器相等,但根据 hashCode 和 equals 不同)。

于 2013-04-10T08:37:37.053 回答