即使Java中List中对象的排序发生变化,如何保持相同的哈希码?
Class A {
private String test1;
private String test2;
}
Class Feature {
private List<A> obj;
/*
HashCode which should return same value even though i change ordering of objects in List
*/
}
当前行为:
> List<A> contains [obj1, obj2, obj3] -> Some hashCode (Ex: 9058203945)
> List<A> contains [obj2, obj1, obj3] -> Some other hashCode (Ex:-23423423)
我想要的是,如果我更改 List 中元素的顺序,我的 List 的 hashCode 应该相同。
有什么帮助吗?
提前致谢
回答
不确定,但我猜您指的是该List#hashCode方法。
元素的排序是 List
a 中包含的元素的顺序List是列表的核心概念。因此,更改顺序会导致完全另一个列表。这两个列表在概念上并不相等,因此它们不会也不应该返回相同的哈希值(除非巧合,如果使用体面的哈希函数,这种情况非常罕见)。
从技术上讲,您可以子类化一个List类并覆盖该hashCode方法。你可以用你自己的hashCode方法做任何你喜欢的事情。但这将是一个非常糟糕的主意,因为它违反了 a 的语义List。
Set
如果您不关心元素的顺序,请使用另一个集合而不是List.
Set很可能是你需要的。ASet持有一堆对象,不一定按任何特定顺序。一些实现以特定顺序迭代,一些不保证任何顺序。
Set < DayOfWeek > setX = Set.of( DayOfWeek.TUESDAY , DayOfWeek.WEDNESDAY );
Set < DayOfWeek > setY = Set.of( DayOfWeek.WEDNESDAY , DayOfWeek.TUESDAY );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
System.out.println( "setX.hashCode() = " + setX.hashCode() );
System.out.println( "setY.hashCode() = " + setY.hashCode() );
System.out.println( "sameHashCode = " + sameHashCode );
跑的时候。
setX.hashCode() = -838114520
setY.hashCode() = -838114520
sameHashCode = 真
这适用于Set.
Set < DayOfWeek > setX =new TreeSet<>() ;
setX.add( DayOfWeek.TUESDAY);
setX.add( DayOfWeek.WEDNESDAY);
Set < DayOfWeek > setY = new HashSet <>();
setY.add( DayOfWeek.WEDNESDAY );
setY.add( DayOfWeek.TUESDAY );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
sameHashCode = 真
那些是上面的枚举对象。它适用于String对象吗?是的。
Set < String > setX = new TreeSet <>();
setX.add( "Alice" );
setX.add( "Bob" );
setX.add( "Carol" );
Set < String > setY = new HashSet <>();
setY.add( "Bob" );
setY.add( "Alice" );
setY.add( "Carol" );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
sameHashCode = 真
Set 是不同的
注意之间的一个主要区别Set和List:
List允许重复。一个对象可以多次添加到列表中,并在该列表中占据多个位置。Set禁止重复。ASet是不同的,只保存对任何特定对象的单个引用。多次添加一个特定对象在第一次之后没有任何影响。
引用SetJavadoc:
不包含重复元素的集合。更正式地说,集合不包含一对元素 e1 和 e2,使得 e1.equals(e2),并且最多包含一个空元素。正如其名称所暗示的那样,该接口对数学集合抽象进行建模。
Set < String > setX = new TreeSet <>();
setX.add( "Alice" );
setX.add( "Bob" );
setX.add( "Carol" );
Set < String > setY = new HashSet <>();
setY.add( "Bob" );
setY.add( "Alice" );
setY.add( "Carol" );
boolean sameHashCode = ( setX.hashCode() == setY.hashCode() );
setY.toString(): [Cindy, Jan, Marsha]