Case-insensitive collections (sets, maps, etc.)

Discussion in 'Java' started by Matt, Mar 15, 2007.

  1. Matt

    Matt Guest

    I have to believe I'm not the first person to have this question.
    However, I'm not having any luck finding a conclusive answer.

    FYI, I'm coding in Java 1.5. Say I have the following:

    Set<String> a = new HashSet<String>();
    Map<String, Object> b = new TreeMap<String, Object>();

    Assume somewhere these are populated.

    When I check the set for a string using a.contains("bob"), the method is
    checking using a case-sensitive search. Similarly, if I did
    b.containsKey("tom"), it's case-sensitive.

    Is it possible to get these methods to perform a comparison
    case-insensitively? Thus, performing:

    a.contains("bob")
    a.contains("BoB")
    a.contains("BOB")

    would all yield the same result?


    Thanks for your time. Cheers,

    Matt
    --
    Matt, Mar 15, 2007
    #1
    1. Advertising

  2. "Matt" <> wrote in message
    news:45f8c618$0$28125$...
    >I have to believe I'm not the first person to have this question. However,
    >I'm not having any luck finding a conclusive answer.
    >
    > FYI, I'm coding in Java 1.5. Say I have the following:
    >
    > Set<String> a = new HashSet<String>();
    > Map<String, Object> b = new TreeMap<String, Object>();
    >
    > Assume somewhere these are populated.
    >
    > When I check the set for a string using a.contains("bob"), the method is
    > checking using a case-sensitive search. Similarly, if I did
    > b.containsKey("tom"), it's case-sensitive.
    >
    > Is it possible to get these methods to perform a comparison
    > case-insensitively? Thus, performing:
    >
    > a.contains("bob")
    > a.contains("BoB")
    > a.contains("BOB")
    >
    > would all yield the same result?
    >
    >
    > Thanks for your time. Cheers,


    Just make a class called jerkString (because it's insensitive) and define
    your own compare. And then you can have it return it's string value when
    asked.

    --
    LTP

    :)
    Luc The Perverse, Mar 15, 2007
    #2
    1. Advertising

  3. Matt

    Lew Guest

    Please do not multi-post. If you truly must reach multiple groups, cross-post
    instead. This will unify your thread so that people don't have to jump around
    all over the place to help you. Why put obstacles in people's path?

    Matt wrote:
    > I have to believe I'm not the first person to have this question.
    > However, I'm not having any luck finding a conclusive answer.
    >
    > FYI, I'm coding in Java 1.5. Say I have the following:
    >
    > Set<String> a = new HashSet<String>();
    > Map<String, Object> b = new TreeMap<String, Object>();
    >
    > Assume somewhere these are populated.
    >
    > When I check the set for a string using a.contains("bob"), the method is
    > checking using a case-sensitive search. Similarly, if I did
    > b.containsKey("tom"), it's case-sensitive.
    >
    > Is it possible to get these methods to perform a comparison
    > case-insensitively? Thus, performing:


    Define a class wrapping String with a natural order based on case-insensitive
    comparison. Use that as a base type in your Collections instead of String.

    -- Lew
    Lew, Mar 15, 2007
    #3
  4. Matt

    Lew Guest

    Lew wrote:
    > Define a class wrapping String with a natural order based on
    > case-insensitive comparison.


    I should have said with equality based on ...

    -- Lew
    Lew, Mar 15, 2007
    #4
  5. Matt

    Lew Guest

    Please do not multi-post. If you truly must reach multiple groups, cross-post
    instead. This will unify your thread so that people don't have to jump around
    all over the place to help you. Why put obstacles in people's path?

    Matt wrote:
    > I have to believe I'm not the first person to have this question. However, I'm not having any luck finding a conclusive answer.
    >
    > FYI, I'm coding in Java 1.5. Say I have the following:
    >
    > Set<String> a = new HashSet<String>();
    > Map<String, Object> b = new TreeMap<String, Object>();
    >
    > Assume somewhere these are populated.
    >
    > When I check the set for a string using a.contains("bob"), the method is checking using a case-sensitive search. Similarly, if I did b.containsKey("tom"), it's case-sensitive.
    >
    > Is it possible to get these methods to perform a comparison case-insensitively? Thus, performing:


    Define a class wrapping String with equality (and hashCode) based on
    case-insensitive comparison. Use that as a base type in your Collections
    instead of String.

    -- Lew
    Lew, Mar 15, 2007
    #5
  6. Matt

    Corona4456 Guest

    On Mar 14, 10:05 pm, Matt <> wrote:
    > I have to believe I'm not the first person to have this question.
    > However, I'm not having any luck finding a conclusive answer.
    >
    > FYI, I'm coding in Java 1.5. Say I have the following:
    >
    > Set<String> a = new HashSet<String>();
    > Map<String, Object> b = new TreeMap<String, Object>();
    >
    > Assume somewhere these are populated.
    >
    > When I check the set for a string using a.contains("bob"), the method is
    > checking using a case-sensitive search. Similarly, if I did
    > b.containsKey("tom"), it's case-sensitive.
    >
    > Is it possible to get these methods to perform a comparison
    > case-insensitively? Thus, performing:
    >
    > a.contains("bob")
    > a.contains("BoB")
    > a.contains("BOB")
    >
    > would all yield the same result?
    >
    > Thanks for your time. Cheers,
    >
    > Matt
    > --


    Why not just force everything to be one or the other by using
    String.toLowerCase()?
    Corona4456, Mar 15, 2007
    #6
  7. Matt

    Lew Guest

    Matt <> wrote:
    >> I have to believe I'm not the first person to have this question.


    Please do not multipost. It makes it hard to follow the thread, and why put
    obstacles in people's path? If you really must reach multiple groups, cross-post.

    -- Lew
    Lew, Mar 15, 2007
    #7
  8. Matt

    Tom Hawtin Guest

    Matt wrote:
    >
    > Set<String> a = new HashSet<String>();
    > Map<String, Object> b = new TreeMap<String, Object>();
    >
    > Assume somewhere these are populated.
    >
    > When I check the set for a string using a.contains("bob"), the method is
    > checking using a case-sensitive search. Similarly, if I did
    > b.containsKey("tom"), it's case-sensitive.


    You can set up a TreeSet or TreeMap to do it quite easily. use
    String.CASE_INSENSITIVE_ORDER as the Comparator.

    For a HashSet/HashMap, "bob", "Bob" and "bOb" would all be in completely
    different places. So if each were possible as a key, you would need to
    search the entire collection. Either write your own loop, or dump it
    into a temporary TreeMap/TreeSet.

    The other obvious solution for unsorted collections, is to canonicalise
    the data first. Even if you wanted to preserve case for a Set, use
    HashMap<String,String> keyed on, say, the lowercase form, and mapping to
    the actual capitalisation. Map.put would replace the capitalised form,
    but ConcurrentMap.putIfAbsent would preserve it.

    Tom Hawtin
    Tom Hawtin, Mar 15, 2007
    #8
  9. Matt

    Matt Guest

    Tom,

    Thanks much - I'll give that a try. String.CASE_INSENSITIVE_ORDER will
    probably do the trick; I wasn't aware of that. I don't have a real need
    to use hashes over trees - the TreeSet/TreeMap should work just as well
    in my application.

    Thanks everyone. Per Corona4456, the reason I'm not using
    toLowerCase(), etc. is to preserve the original case for display. As
    Tom suggested below, I could in fact use a secondary map to hash the
    case-sensitive keys to a case-insensitive form.

    Lew - thanks for the note. I hardly ever post on the newsgroups (first
    time on the *java* newsgroup), so I didn't think to cover both bases
    with a single message, nor that it would make a big difference.

    Thanks all. Cheers,

    Matt
    --

    Tom Hawtin wrote:
    > Matt wrote:
    >>
    >> Set<String> a = new HashSet<String>();
    >> Map<String, Object> b = new TreeMap<String, Object>();
    >>
    >> Assume somewhere these are populated.
    >>
    >> When I check the set for a string using a.contains("bob"), the method
    >> is checking using a case-sensitive search. Similarly, if I did
    >> b.containsKey("tom"), it's case-sensitive.

    >
    > You can set up a TreeSet or TreeMap to do it quite easily. use
    > String.CASE_INSENSITIVE_ORDER as the Comparator.
    >
    > For a HashSet/HashMap, "bob", "Bob" and "bOb" would all be in completely
    > different places. So if each were possible as a key, you would need to
    > search the entire collection. Either write your own loop, or dump it
    > into a temporary TreeMap/TreeSet.
    >
    > The other obvious solution for unsorted collections, is to canonicalise
    > the data first. Even if you wanted to preserve case for a Set, use
    > HashMap<String,String> keyed on, say, the lowercase form, and mapping to
    > the actual capitalisation. Map.put would replace the capitalised form,
    > but ConcurrentMap.putIfAbsent would preserve it.
    >
    > Tom Hawtin
    Matt, Mar 15, 2007
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tee
    Replies:
    3
    Views:
    7,767
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  2. Replies:
    3
    Views:
    11,092
  3. Replies:
    1
    Views:
    2,457
    Mark P
    Apr 6, 2007
  4. Kevin Walzer

    Re: PIL (etc etc etc) on OS X

    Kevin Walzer, Aug 1, 2008, in forum: Python
    Replies:
    4
    Views:
    370
    Fredrik Lundh
    Aug 13, 2008
  5. Xah Lee
    Replies:
    4
    Views:
    932
Loading...

Share This Page