Multimap finds instance on containsValue() despite equals() and hashCode() returning different values. How can that be?

StackOverflow https://stackoverflow.com/questions/22092237

  •  18-10-2022
  •  | 
  •  

Domanda

I constructed a TreeMultimap and wanted to add instances of a Wedge class of mine. But it refused to add more than one. I was kind of a loss as I had implemented equals and hashCode. What seemed more strange is that when I invoke the methods in the debugger to check whether I didn't make an error, these methods on separate objects return different values. Therefore, it seems strange that the check for containment returns true. Here some code:

@NonNullByDefault
public class Wedge extends Corona
{
    /** Field of the description to display for the wedge. */
   private String description;

   //Fields and other unrelated methods.        

   /**
    * {@inheritDoc}<br><br>
    * Method for determining if both coronas are equal.
    * Returns true if both share the same description.
    */
   @Override
   public boolean equals(@Nullable Object object)
   {
       if(object == null) return false;
       if(object == this) return true;

       if(object instanceof Wedge)
       {
           return description.equals(((Wedge) object).description);
       }
       return false;
    }

    /**
     * {@inheritDoc}<br><br>
     * Method for determining the hash code based on the description.
     */
    @Override
    public int hashCode()
    {
        return description.hashCode();      
    }
}

The code is used, more or less, as follows in the simplified code:

/** The visual components to display as part of the widget. It's background. */
public Multimap<Integer, Corona> coronas = TreeMultimap.create();

// More interesting fields and methods.
/** 
 * Method for adding a corona to a given handle.
 * @param handleID 
 *      The identifier of the handle for which to add the corona.
 * @param corona 
 *      The corona to display on the handle.
 * @return 
 *      An instance of the builder for chain calling.
 */
@SuppressWarnings("unchecked")
public B withCorona(int handleID, Corona corona)
{       
    coronas.put(handleID, corona);
    return (B) this;
}

The code is part of a builder object. Please excuse the generics. handleID is a key that I use to bind corona instances. It behaves as expected. The coronavariable contains different instances of coronas as the method is called in a loop to add all Corona instances.

Now, as soon as I add the first Wedge tests like coronas.containsValue(corona) return true even though I constructed a new Wedge instance and passed it to the method. As mentioned before, tests using corona.equals(coronaInTheMap) or corona.hashCode() == hashCodeOfCoronaInMap return different values.

Descriptions are set in the constructor and never modified!

I have searched for the error but am stomped. I would need your assistance!

È stato utile?

Soluzione

TreeMultimap uses Comparable rather than equals and hashCode. From the JavaDoc:

Implementation of Multimap whose keys and values are ordered by their natural ordering or by supplied comparators. In all cases, this implementation uses Comparable.compareTo(T) or Comparator.compare(T, T) instead of Object.equals(java.lang.Object) to determine equivalence of instances.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top