users@jsr311.java.net

Re: Case insensitive map

From: Bill Burke <bburke_at_redhat.com>
Date: Tue, 02 Sep 2008 10:02:50 -0400

Reto Bachmann-Gmür wrote:
> Bill Burke wrote:
>> I wrote a CaseInsensitiveMap. I don't see what the problem is.
> 1. To which object are instances of your class equals?
> 2. How to you calculate the hashCode?
>

Go see for yourself:

http://resteasy.svn.sourceforge.net/viewvc/resteasy/trunk/jaxrs/resteasy-jaxrs/src/main/java/org/jboss/resteasy/util/CaseInsensitiveMap.java?view=markup

Its probably not a perfect implementation, but, IIRC, it was pretty damn
close. Granted, what I really wanted was a case-insensitive lookup of
headers, so I didn't test much beyond that, but I'm confident I could
make it work... Then again, I'm usually overconfident.

> If you do consider the case of the keys (i.e. use the keys as added)
> this is against the concept of case-insensitiveness. Also you would have
> two maps which result as different even though they answer the same
> value for the same set of keys. If you take the hashCode of key in
> specific casing you're making an arbitrary choice and it not longer
> workds properly across different implementations (which is why
> java.util.Map defines how these Methods are to be implemented).
>

Internally, you create your own CaseInsensitiveKey and your own internal
map based on that.

> java.util.Map.get(key) is defined as:
>> More formally, if this map contains a mapping from a key k to a value
>> v such that (key==null ? k==null : key.equals(k)), then this method
>> returns v; otherwise it returns null. (There can be at most one such
>> mapping.)
>
> 3. How do you implement your Map do satisfy this inherited requirement
> and be case-insensitive for keys?
>

What you are logically doing is two things:

1) Overriding the behavior of hashCode() to be consistent in a
case-insensitive way

2) Overriding the behavior of String.equals().

In the implementation, what you have to do is write *a lot* of wrapper
classes to provide this logical behavior.

> 4. Do map.comtainsKey(k) and map.keySet().contains(k) return the same
> value?

Yes.

> (do you return a case-insensitive set)
>

IIRC, I do. There's probably bugs, but, I think I was on to the right
approach.


-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com