点击上方“猿芯”,选择“设为星标”
后台回复"1024",有份惊喜送给面试的你
在Java中, map是一个非常好用的数据结构, 无论是索引还是性能优化, 经常会用到map
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
可以看到, 这个数据结构有一个特点, 就是一个key对应一个value, 这里问题就来了, 那我的业务需要两个或以上的key值来对应一个value的时候, 咋办?
方案一: 把map的value也变成map
这种方式就是把之前的map中的value替换成map, 简单理解为嵌套的map
Map<String, Map<String, String>> map1 = new HashMap<>();
HashMap<String, String> map2 = new HashMap<>();
map2.put("key2", "value");
map1.put("key1", map2);
这种方案的好处就是只用map就搞定了, 但是因为是嵌套的结构, 两个key的话代码还能看, 要是3 - 5个key的话这个嵌套层级就简直了, 代码写出来可能要被骂的
方案二: 多个key先变成hash
方案一的问题是代码嵌套层次太多, 代码可读性不高, 那我们就试图把多个key整合成一个key, 可以考虑哈希函数
Map<Integer, String> map = new HashMap<>();
int hash = Objects.hash("key1", "key2");
map.put(hash, "value");
当然这种方法也会有问题, 就是看到map的定义, 并不知道哪些业务字段是key, 需要进一步看key的定义, 这倒不是啥大问题. 要是自定义hash值, 需要仔细思考一下, 直接使用Objects.hash() 这个方法可能会面临hash碰撞的情况, 尤其是当数据量大的时候, 因为亲自碰到过这个问题, 所以觉得直接使用还是有风险的.
方案三: Guava Table
如果你一般只需要两个key的话, Google的Guava的库能给你很好的选择
Table<String, String, String> table = HashBasedTable.create();
table.put("key1", "key2", "value");
虽然是Table, 但其实和map的使用方式完全一致, 也能很方便的取出rowKeySet和columnKeySet, 如果是两个key的话, 推荐此方式, 代码几乎和map的写法差不多, 缺点就是只支持两个key, 三个key以上就很尴尬
方案四: MultiKeyMap
最后一种方案, 就是多key的终极方案, 当然了, 终极方案也是有限制的, 最多一次支持传5个key, 如果超出5个key的话, 还是参考一下方案二吧.
MultiKeyMap multiKey = new MultiKeyMap();
multiKey.put("key1", "key2", "value");
看起来这个方法很完美, 但是有个最大的问题就是此方法不支持对象类型, key和value都会被视为Object, 用起来就没有Java面向对象的感觉了, 往往还需要类型转换才行
String value = (String) multiKey.get("key1","key2");
这样的代码多了就会生硬, 到处都是类型转换, 维护成本很高, 再者就是取key和遍历的时候不是很友好, 会让代码过度的繁杂.
往期推荐
作者简介:猿芯,一枚简单的北漂程序员。喜欢用简单的文字记录工作与生活中的点点滴滴,愿与你一起分享程序员灵魂深处真正的内心独白。我的微信号:WooolaDunzung,公众号【猿芯】输入 1024 ,有份面试惊喜送给你哦。
< END >
【猿芯】
微信扫描二维码,关注我的公众号。
分享不易,莫要干想,如果觉得有点用的话,动动你的发财之手,一键三连击:分享、点赞、在看,你们的鼓励是我分享优质文章的最强动力 ^_^
分享、点赞、在看,3连3连!