Map<Pattern, Object> fails to find key
I have the following code:
List<Pattern> patterns = Lists.newArrayList(Pattern.compile("blah"), Pattern.compile("blah2"));
Map<Pattern, String> map = new HashMap<Patter, String>();
map.put(patterns.get(0), "1");
map.put(patterns.get(1), "2");
Assert.assertTrue(map.containsKey(patterns.get(0)));
The assert fails!
Why would this be? First, I am surprised that the Pattern
class does not implement equals
and hashCode
based on the pattern. But even if it didn't, doesn't Objec开发者_运维问答t
use the memory address for the hashCode
and equals
so that as long as I am passing the same Object
instance, the key should be found?
Edit: Sorry folks. Here is what I actually had. Forgot that transform
will create a new instance each time access is done.
List<Pattern> patterns = Lists.transform(Lists.newArrayList("blah1", "blah2"), toPattern);
Given your code doesn't compile, I can only assume this is not the code you are running.
List<Pattern> patterns = Arrays.asList(Pattern.compile("blah"), Pattern.compile("blah2"));
Map<Pattern, String> map = new HashMap<Pattern, String>();
map.put(patterns.get(0), "1");
map.put(patterns.get(1), "2");
System.out.println(map.containsKey(patterns.get(0)));
prints
true
You can still use maps and sets, even if objects don't have proper hashCode/equals. Instead it's nearly always possible to use the TreeMap and a custom comparator:
final Map<Pattern, String> map = new TreeMap<Pattern, String>(
new Comparator<Pattern>()
{
@Override
public int compare(final Pattern o1, final Pattern o2)
{
return o2.pattern().compareTo(o2.pattern());
}
});
The only problem here - it's quite difficult to express genuine equality of regexps. E.g. regexp "a|b" is exactly the same as "b|a". But maybe string comparison is enough for you.
Yet another way is to wrap the Pattern in your class with desired hashCode/equals and use it as the hash map's key.
精彩评论