map忽略Key大小写敏感度
在面试时被问到一个问题,map如何使key忽略大小写,需要重写些什么方法之类的问题?当时有点懵,一下没反应过来。不区分大小写,简单来说就是put数据进map的时候,最终map中该类型的key只能有一个(比如AAA,aaa,AaA),在取值的时候,可以get所有该类型(由字母a组成的三位字符)的key取出同一个值。
以下是总结出来的一些方法:
1.写比较器
首先最原始的方法,手写一个比较器试试,
public static void main(String[] args) {
Map<String, Object> map = new TreeMap<String, Object>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.compareToIgnoreCase(o2) == 0) {
return 0;
}
return 1;
}
});
map.put("AAA", "AAAAAAAAAA");
map.put("aaa", "aaaaaaaaaa");
map.put("MMM", "MMMMMMMMMMM");
map.put("mmm", "mmmmmmmmmmm");
map.put("SSS", "SSSSSSSSSSSSS");
map.put("sss", "ssssssssssss");
for (Map.Entry<String, Object> et : map.entrySet()) {
System.out.println("遍历map:--" + et.getKey() + "----" + et.getValue());
}
System.out.println(map.get("aaa"));
System.out.println(map.get("mmm"));
System.out.println(map.get("sss"));
}
控制台输出结果是:
遍历map:--AAA----aaaaaaaaaa
遍历map:--MMM----mmmmmmmmmmm
遍历map:--SSS----ssssssssssss
null
mmmmmmmmmmm
ssssssssssss
由以上可以看出,有个值为null,取值取不到,(我到最后没搞明白啥原因,请大佬们指教),所以又重写了map的get方法,如下
public static void main(String[] args) {
Map<String, Object> map = new TreeMap<String, Object>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.compareToIgnoreCase(o2) == 0) {
return 0;
}
return 1;
}
}) {
@Override
public Object get(Object key) {
for (Map.Entry<String, Object> et : this.entrySet()) {
if (et.getKey().equalsIgnoreCase(key.toString())) {
return et.getValue();
}
}
return null;
}
};
输出结果为:
aaaaaaaaaa
mmmmmmmmmmm
ssssssssssss
三个值都顺利取出。
由于在下是个小白,比较器写的不咋地,留下了隐患,欢迎给位更正;
2.map传参数
试完了原始的,开始试试简单的方法了,有现成的不用是傻子,不是我们程序猿的风格,这个方法就简单多了,用TreeMap的构造传参。直接传个比较器进去 :String.CASE_INSENSITIVE_ORDER
直结上代码:
public static void main(String[] args) {
/**
* String.CASE_INSENSITIVE_ORDER:相当于传入一个比较器,功能类似于compare
*/
Map<String, Object> map = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
map.put("AAA", "AAAAAAAAAA");
map.put("AAa", "aaaaaaaaaa");
map.put("MMM", "MMMMMMMMMMM");
map.put("MMm", "mmmmmmmmmmm");
map.put("SSS", "SSSSSSSSSSSSS");
map.put("SSs", "ssssssssssss");
map.put("aaa", "AAAAAaaaa");
for (Map.Entry<String, Object> et : map.entrySet()) {
System.out.println("map输出:--" + et.getKey() + "----" + et.getValue());
}
/**
* 根据大小写不同的key取值,取到的是同一个值,
* map在做put的时候,保留第一次添加的key作为和后面比较的条件,
* 后面的如有key相同,则替换掉之前的值, 因此最终保留的是第一个key和最后一个value,
*/
System.out.println(map.get("AAa"));
System.out.println(map.get("AAA"));
System.out.println(map.get("aaA"));
System.out.println(map.get("aaa"));
// 之前不存在的key一样可以取值
System.out.println("之前不存在的key:---" + map.get("Aaa"));
}
map输出:--AAA----AAAAAaaaa
map输出:--MMM----mmmmmmmmmmm
map输出:--SSS----ssssssssssss
AAAAAaaaa
mmmmmmmmmmm
ssssssssssss
之前不存在的key:---AAAAAaaaa
CaseInsensitiveMap()
CaseInsensitiveMap() 是apache家的,该类的主要作用就是不区分大小写,和ConcurrentHashMap意义上有点类似,不用传参,也不要写比较器,更不要重写方法
使用方法:
首先,我用maven导包:
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
不适用maven的可以去下载org.apache.commons jar包,该类在
代码:
public static void main(String[] args) {
Map<String, Object> map = new CaseInsensitiveMap();
map.put("AAA", "AAAAAAAAAA");
map.put("aaa", "aaaaaaaaaa");
map.put("MMM", "MMMMMMMMMMM");
map.put("mmm", "mmmmmmmmmmm");
map.put("SSS", "SSSSSSSSSSSSS");
map.put("sss", "ssssssssssss");
for (Map.Entry<String, Object> et : map.entrySet()) {
System.out.println("遍历map:--" + et.getKey() + "----" + et.getValue());
}
System.out.println(map.get("AAa"));
System.out.println(map.get("MMm"));
System.out.println(map.get("SSs"));
}
输出
遍历map:--mmm----mmmmmmmmmmm
遍历map:--aaa----aaaaaaaaaa
遍历map:--sss----ssssssssssss
aaaaaaaaaa
mmmmmmmmmmm
ssssssssssss
整体来说还是很简单的,当然如果一定要实现一个手写的比较器的话,虽然是麻烦点,但也不是不行,但是具体的判断逻辑就靠大伙摸索完了通知我下,多谢啦,希望对你们能有点帮助,请大佬们多指教。。。