即使 Java 列表中对象的排序发生变化,如何保持相同的哈希码?

How to maintain same hashcode even though ordering of object change in List in Java?

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)

What i want is my hashCode of List should be same if i change the ordering of elements in List.

有什么帮助吗?

提前致谢

不确定,但我猜你指的是 List#hashCode 方法。

元素的排序正是 List

的定义

一个List中元素的排列顺序是列表的核心概念。因此,更改顺序会导致出现另一个列表。这两个列表在概念上并不相等,因此它们不会也不应该 return 相同的哈希值(除非是异常巧合,如果使用体面的 hash function,这种情况极为罕见)。

从技术上讲,您可以子class 一个 List class 并覆盖 hashCode 方法。您可以在自己的 hashCode 方法中做任何您想做的事情。但这将是一个 非常 的坏主意,因为它违反了 List.

的语义。

Set

如果您不关心元素的顺序,请使用另一个集合而不是 List

Set 可能是您所需要的。 Set 包含一堆对象,不一定按任何特定顺序排列。有些实现按特定顺序迭代,有些不承诺任何顺序。

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 = true

这适用于 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 = true

那些是上面的枚举对象。它适用于 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 = true

Set 不同

注意 SetList 之间的一个主要区别:

  • List 允许重复。一个对象可以多次添加到列表中,并在该列表中占据多个位置。
  • Set 禁止重复。 Set 是不同的,仅包含对任何特定对象的单个引用。多次添加一个特定对象在第一次后没有效果。

引用 Set Javadoc:

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.

Set < String > setY = new TreeSet <>();
setY.add( "Jan" );
setY.add( "Marsha" );
setY.add( "Marsha" );
setY.add( "Marsha" );
setY.add( "Cindy" );

setY.toString(): [Cindy, Jan, Marsha]