Case insensitive keys using Collections

F

fritz-bayer

Hi,

I'm looking for container (hashmap or set), into which I can put key
value objects that I can latter retrieve using a string as a key in a
case insensitive manner.

It's important that the original key stays unchanged. For example, it's
NOT ok to transform the key in the key value object into upper or
lower.

Here is some hypothetical code to illustrate the requested behaviour:

// This is our case insensitive hashmap.
CaseinsenstiveHashMap hm = new CaseinsenstiveHashMap();

KeyValueObject keyvalue = new KeyValueObject();
keyvalue.setKey("coNtent-LengtH", "12024");

hm.put(keyValue.getKey(), keyValue);

// Keys are case insenstive !
assertEquals("12024",
((KeyValueObject)hm.get("Content-Lenght")).getValue() );
assertEquals("12024",
((KeyValueObject)hm.get("CONTENT-LENGTH")).getValue() );
assertEquals("12024",
((KeyValueObject)hm.get("cOnTeNt-lEnGtH")).getValue() );

// The original key is unchanged !
assertEquals("coNtent-LengtH",((KeyValueObject)hm.get("cOnTeNt-lEnGtH")).getKey());

I tried overwriting the hashCode() and equals() fucntion but then I
won't be able to retrieve the objects using a simple String in the
get("simpleString") function of the hashtable!

So I guess I have to use the Comparator interface to compare Strings
with KeyValueObjects?

But I'm not sure, whether or not the Comparator is also being used when
retrieveing objects. Isn't it only consulted when inserting new
elements to preserve order?

Fritz
 
C

Chris Smith

It's important that the original key stays unchanged. For example, it's
NOT ok to transform the key in the key value object into upper or
lower.

Here is some hypothetical code to illustrate the requested behaviour:

Fortunately, there is a very easy solution to your problem. Your map is
basically a Map<String,KeyValueObject> where KeyValueObject keeps both
the key and value. You can convert the string to a constant case, but
leave key from the KeyValueObject the same. That preserves the original
case, while also storing the data in a case-insensitive manner.
// This is our case insensitive hashmap.
CaseinsenstiveHashMap hm = new CaseinsenstiveHashMap();

Just use a normal HashMap here.
KeyValueObject keyvalue = new KeyValueObject();
keyvalue.setKey("coNtent-LengtH", "12024");

hm.put(keyValue.getKey(), keyValue);

hm.put(keyValue.getKey().toLowerCase(), keyValue);
// Keys are case insenstive !
assertEquals("12024",
((KeyValueObject)hm.get("Content-Lenght")).getValue() );
assertEquals("12024",
((KeyValueObject)hm.get("CONTENT-LENGTH")).getValue() );
assertEquals("12024",
((KeyValueObject)hm.get("cOnTeNt-lEnGtH")).getValue() );

You then need to call toLowerCase() on the String constants when
retrieving from the map.
// The original key is unchanged !
assertEquals("coNtent-LengtH",((KeyValueObject)hm.get("cOnTeNt-lEnGtH")).getKey());

And no changes at all here, because the KeyValueObject still holds the
original key.

Alternatively, Neal's answer works fine. However, it's asymptotic
complexity differs if you care about performance for extremely large
data sets.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top