开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜