Java中的链接映射,如果键的顺序不同,则不相等

Java中的链接映射,如果键的顺序不同,则不相等,java,linkedhashmap,Java,Linkedhashmap,Java或第三方库中是否有保留插入顺序的映射(类似于LinkedHashMap),该映射在比较期间也会检查键的顺序(equals()和hashCode()方法)?因此Map(a=>1,b=>2)将不同于Map(b=>2,a=>1) 与下面类似,但我不想重新发明和维护车轮: public class EqualityStrictLinkedMap<K, V> extends ForwardingMap<K, V> { ... @Override p

Java或第三方库中是否有保留插入顺序的映射(类似于LinkedHashMap),该映射在比较期间也会检查键的顺序(
equals()
hashCode()
方法)?因此
Map(a=>1,b=>2)
将不同于
Map(b=>2,a=>1)

与下面类似,但我不想重新发明和维护车轮:

public class EqualityStrictLinkedMap<K, V> extends ForwardingMap<K, V>
{
    ...

    @Override
    public boolean equals(Object o)
    {
        if (!(o instanceof Map))
            return false;
        Map<K, V> that = (Map<K, V>) o;
        return Iterables.elementsEqual(entrySet(), that.entrySet());
    }

    @Override
    public int hashCode()
    {
        int h = 1;
        for (Map.Entry<K, V> entry: entrySet()) {
            h = (h*31 + Objects.hashCode(entry.getKey()))*31 + Objects.hashCode(entry.getValue());
        }
        return h;
    }
}
公共类EqualityStrictLinkedMap扩展了ForwardingMap
{
...
@凌驾
公共布尔等于(对象o)
{
如果(!(映射的实例))
返回false;
Map that=(Map)o;
返回Iterables.elementsEqual(entrySet(),that.entrySet());
}
@凌驾
公共int hashCode()
{
int h=1;
对于(Map.Entry:entrySet()){
h=(h*31+Objects.hashCode(entry.getKey())*31+Objects.hashCode(entry.getValue());
}
返回h;
}
}

Map接口指定equals和hashCode必须忽略顺序。如果不想忽略订单,则不能实现
Map
接口。(当然,你可以有一个
asMap()
视图。)在Guava或JDK中,以及在我所见过的任何库中,肯定没有任何东西能为你做到这一点。@LouisWasserman(A)你能举一个文档中关于
等于
哈希码
忽略顺序的部分吗?我正在阅读Java11中的Javadoc。我没有看到任何这样的部分,但我可能是误解。(B) 看起来你应该回答你的评论,这样这个问题就可以结束了。我相信这是指如果两个
Map
s的条目集相等,那么这两个条目集是相等的,如果它们具有相同的大小并且包含相同的元素,那么这两个条目集是相等的。注意(不管上面的说法是否正确):没有什么可以阻止您实现
Map
接口,而是添加了一些
isEqualsIncludingOrder
类型方法。这可能会起作用,@BeUndead,尽管我想将其用作键,因此直接重写
equals
更有意义。包装到另一个对象并调用特定的方法会有所帮助,但会增加不必要的复杂性。无论如何,谢谢你的建议,我有点惊讶,还没有人创造了它。我认为合同(无论如何都不是很明确)可以放宽,如果它服务于特定的目的,尽管明显的缺点是与其他Map实现的匹配不一致。在其他情况下,其他数据结构的行为与原始契约不一致。