How to ignore the case sensitive when we look for a key in the Map?
Why not use a TreeMap
instead of HashMap
, then you could specify a Comparator with a case insensitive order (String.CASE_INSENSITIVE_ORDER
):
public static void main(String[] args) throws Exception {
Map<String, Integer> lookup =
new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);
lookup.put("One", 1);
lookup.put("tWo", 2);
lookup.put("thrEE", 3);
System.out.println(lookup.get("Two"));
System.out.println(lookup.get("three"));
}
Outputs:
2
3
CaseInsensitive Map Key Java
You can do it like this:
Map<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
See this question.
However, note the performance implications of using a TreeMap
instead of a HashMap
, as mentioned by Boris in the comments.
Is there any efficient way to have a case insensitive string as a HashMap key?
The easiest way to do it is to use UniCase
as a key:
use unicase::UniCase;
type Words = std::collections::HashMap<UniCase, u32>;
If I understand their documentation, UniCase::new("The")
stores the actual string "The"
in it, but if you compare it with Unicase::new("the")
, you will see that it is the same string.
How to check for key in a Map irrespective of the case?
Not with conventional maps.
"abc" is a distinct string from "ABC", their hashcodes are different and their equals() methods will return false with respect to each other.
The simplest solution is to simply convert all inputs to uppercase (or lowercase) before inserting/checking. You could even write your own Map
wrapper that would do this to ensure consistency.
If you want to maintain the case of the key as provided, but with case-insensitive comparison, you could look into using a TreeMap and supplying your own Comparator that will compare case-insensitively. However, think hard before going down this route as you will end up with some irreconcilable inconsistencies - if someone calls map.put("abc", 1)
then map.put("ABC", 2)
, what case is the key stored in the map? Can you even make this make sense? Are you comfortable with the fact that if someone wraps your map in a standard e.g. HashMap
you'll lose functionality? Or that if someone happens to be iterating through your keyset anyway, and does their own quick "contains" check by using equals()
you'll get inconsistent results? There will be lots of other cases like this too. Note that you're violating the contract of Map by doing this (as key equality is defined in terms of the equals() method on the keys) so it's really not workable in any sense.
Maintaining a strict uppercase map is much easier to work with and maintain, and has the advantage of actually being a legal Map implementation.
Ignore case while comparing string with keyvalue in the hashmap
If you see the implementation of HashMap getKey method you have to pass the proper key to generate the hash value and get the actual value from that bucket.
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
Three solutions
Map<String, String> pref = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
OR
Map<String, String> map = new CaseInsensitiveMap<String, String>();
OR
Looping through map with the ignore case
Map with case insensitive get, remove and containsKey
You can't do that with HashMap
. Use a TreeMap
instead:
new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
For highly concurrent version, use ConcurrentSkipListMap
:
new ConcurrentSkipListMap<String, String>(String.CASE_INSENSITIVE_ORDER)
Since you don't care about actual ordering, the String.CASE_INSENSITIVE_ORDER
is fine for this. If locale-sensitive ordering is required, you need to supply a Collator
instead, e.g.
Collator.getInstance(Locale.forLanguageTag("es-ES"))
Case Insensitive map in Java
You can convert the strings into lower case while putting into the map.
Map<String, Integer> map = new LinkedHashMap<>();
for (String w : data) {
Integer n = map.get(w.toLowerCase());
n = (n == null) ? 1 : ++n;
map.put(w.toLowerCase(), n);
}
System.out.println(map);
Case insensitive key for hashmap kotlin?
For this, you would need either to provide some extension function that would put and get the entry in some defined way (e.g. using every time lowercase()
String's method) keeping keys case insensitive
fun HashMap<String, Int>.putInsensitive(k: String, v: Int) {
this[k.lowercase()] = v
}
fun HashMap<String, Int>.getInsensitive(k: String, v: Int): Int? = this[k.lowercase()]
or provide your own Map
interface implementation (it could even inherit from HashMap)
class InsensitiveHashMap<V> : HashMap<String, V>() {
override fun put(key: String, value: V): V? = super.put(key.lowercase(), value)
override fun get(key: String): V? = return super.get(key.lowercase())
}
Case insensitive hashmap for strings in java
Simple fix;
CaseInsensitiveMap stuff = new CaseInsensitiveMap();
prints out;
{happy=11}
11
{happy=11}
CaseInsensitiveMap
is extending HashMap<String, Integer>
so it is a subclass of it, the fact that you reference stuff
as HashMap
(as the superclass) allows it to use default get
method. You can even see in an IDE that your custom get(String)
in CaseInsensitiveMap
is not even used.
Only overridden methods will be used if you use superclass reference for a subclass, as you've done in your code. That is why only your custom put(String, Integer)
method works since it is overriding the method in super
.
Referencing Subclass objects with Subclass vs Superclass reference for more info on that issue.
Related Topics
Java Wait for Thread to Finish
Date Format Parse Exception - "Eee Mmm Dd Hh:Mm:Ss Z Yyyy"
Immutable VS Unmodifiable Collection
How to Get the File Name from a String Containing the Absolute File Path
Should I Call Ugi.Checktgtandreloginfromkeytab() Before Every Action on Hadoop
Updating UI from Different Threads in Javafx
Invalid Thread Access Error with Java Swt
Java, How to Add Library Files in Netbeans
Can You Explain the Httpurlconnection Connection Process
How to Initialize an Arraylist with All Zeroes in Java
Returning Overlapping Regular Expressions
Maven: Failed to Read Artifact Descriptor
In Java, Is It More Efficient to Use Byte or Short Instead of Int and Float Instead of Double
How to Embed Binary Data in Xml
How to Generate Cdata Block Using Jaxb