Reputation: 2119
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
*/
}
Current behaviour:
> 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.
Any help?
Thanks in Advance
Upvotes: 4
Views: 2610
Reputation: 338775
Not sure, but I guess you are referring to the List#hashCode
method.
List
The order of the elements contained in a List
is the core concept of a list. So changing the order results in another list altogether. Those two lists are not conceptually equal, so they do not, and should not, return the same hash value (except by freak coincidence, which is exceedingly rare if using decent hash function).
Technically you could subclass a List
class and override the hashCode
method. You could do whatever you like in your own hashCode
method. But this would be a very bad idea as it violates the semantics of a List
.
Set
If you do not care about the order of your elements, use another collection instead of List
.
Set
is likely what you need. A Set
holds a bunch of objects, not necessarily in any particular order. Some implementations iterate in a certain order, some do not promise any order.
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 );
When run.
setX.hashCode() = -838114520
setY.hashCode() = -838114520
sameHashCode = true
This works across different implementations of 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
Those were enum objects above. Does it work with String
objects? Yes.
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
is distinctBe aware of one major difference between Set
and List
:
List
allows duplicates. One object can be added to the list multiple times, and take multiple slots in that list.Set
forbids duplicates. A Set
is distinct, holding only a single reference to any particular object. Adding one particular object multiple times has no effect after the first time.To quote the 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]
SequencedCollection
By the way, Java 21 brought sequenced collections. See JEP 431: Sequenced Collections.
The more general super-interface of both List
and NavigableSet
/SortedSet
is SequencedCollection
.
SequencedCollection < Integer > sequence = List.of( 42 , 7 , 99 ) ;
Upvotes: 8