map忽略Key大小写敏感度

1 篇文章 0 订阅

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包,该类在
注意是commons-collections包
代码:

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

整体来说还是很简单的,当然如果一定要实现一个手写的比较器的话,虽然是麻烦点,但也不是不行,但是具体的判断逻辑就靠大伙摸索完了通知我下,多谢啦,希望对你们能有点帮助,请大佬们多指教。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值