问题
It's clear that equals()
(and of course hashCode()
) are valuable when you're dealing with immutable value objects -- map keys, strongly typed field values that you need to compare across the objects that contain them, etc.
But apart from value objects, how often is it really likely that you'll have two independently constructed instances and want them to be equal
?
It's hard for me to imagine a realistic scenario where referential equality wouldn't, de facto, get you what you want; and in those specific cases, it seems like a scenario-specific equivalence method (isEquivalentTo(Foo)
rather than equals(Object)
) would be safer. Particularly for mutable objects?
What's the use case for equals()
in non-value types?
回答1:
Um. Set<E>
is mutable, and has a (useful) definition of equals()
. That doesn't seem useless...
回答2:
From docs.oracle.com:
Interface List<E>
boolean contains(Object o)
Returns true if this list contains the specified element.
More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
So, overriding equals
is useful for this (and other) language constructs.
Consider this (sorry, it's in C#):
class MimeType
{
public string Name { get; set; }
public string Extension { get; set; }
public override bool Equals(object obj)
{
var other = obj as MimeType;
if (other == null) return false;
return other.Name == Name;
}
}
class Program
{
void Main()
{
var jpeg1 = new MimeType();
jpeg1.Name = "image/jpeg";
jpeg1.Extension = ".jpg";
var jpeg2 = new MimeType();
jpeg2.Name = "image/jpeg";
jpeg2.Extension = ".jpeg";
var list = new List<MimeType>();
list.Add(jpeg1);
if (!list.Contains(jpeg2))
list.Add(jpeg2);
}
}
In the above example, the jpeg2
object will not be added to the list, because the list already contains an equivalent instance.
Update:
Just for fun, I added the Extension
member to the MimeType
class.
来源:https://stackoverflow.com/questions/9089335/apart-from-immutable-value-objects-when-should-i-override-equals