微信搜索lxw1234bigdata | 邀请体验:数阅–数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

Java实现的双向Map,支持重复Value

编程语言 lxw1234@qq.com 10607℃ 0评论

关键字:Java双向Map、DualHashBidiMap

项目中有个需求,需要根据即时修改Map结构中的Value值,比如,将Map中所有value=V1的记录改成value=V2,key保持不变。

数据量比较大,遍历Map性能太差,这就需要根据Value先找到Key,然后去修改。

即:既要根据Key找Value,又要根据Value找Key。

commons-collections中的DualHashBidiMap实现了双向Map的功能,但悲剧的是,Value必须唯一。

自己简单实现了一个双向Map,支持根据Key和Value查找,核心思想是相当于额外保存了一份V->K的映射关系,当根据V查找时候,

先快速找到哪些V存在于哪些K中,然后再根据这些K去找,就很快了。类似于索引表。

代码不够完善,发现Bug还望多多指正。

  1. package com.lxw1234.map
  2.  
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import java.util.Set;
  6. import java.util.concurrent.ConcurrentHashMap;
  7.  
  8. /**
  9. *
  10. * @author lxw的大数据田地 - http://lxw1234.com
  11. * @param
  12. * @param
  13. */
  14. public class MyMap<K,V> {
  15. private Map<K,V> kMap = new HashMap<K,V>();
  16. private Map<V,ConcurrentHashMap<K,String>> vMap = new HashMap<V,ConcurrentHashMap<K,String>>();
  17. private final static String VV = "1";
  18. public boolean put(K k,V v) {
  19. boolean result = false;
  20. if(null == k || null == v) return result;
  21. if(kMap.containsKey(k)) {
  22. vMap.get(kMap.get(k)).remove(k);
  23. //vMap.remove(kMap.get(k));
  24. }
  25. kMap.put(k, v);
  26. if(vMap.containsKey(v)) {
  27. vMap.get(v).put(k,VV);
  28. } else {
  29. ConcurrentHashMap<K,String> set = new ConcurrentHashMap<K,String>();
  30. set.put(k,VV);
  31. vMap.put(v, set);
  32. }
  33. return true;
  34. }
  35. public boolean containsKey(K k) {
  36. return kMap.containsKey(k);
  37. }
  38. public boolean containsValue(V v) {
  39. return vMap.containsKey(v);
  40. }
  41. public Set keySet(){
  42. return kMap.keySet();
  43. }
  44. public Set valueSet() {
  45. return vMap.keySet();
  46. }
  47. public V getByKey(K k) {
  48. return kMap.get(k);
  49. }
  50. public ConcurrentHashMap<K,String> getByValue(V v) {
  51. return vMap.get(v);
  52. }
  53. public String toString() {
  54. return kMap.toString();
  55. }
  56. public static void main(String[] args) {
  57. MyMap<String,String> map = new MyMap<String,String>();
  58. map.put("k1", "v1");
  59. map.put("k2", "v2");
  60. map.put("k3", "v1");
  61. map.put("k4", "v2");
  62. System.out.println("k1 -> " + map.getByKey("k1"));
  63. System.out.println("v1 -> " + map.getByValue("v1").keySet());
  64. System.out.println("v2 -> " + map.getByValue("v2").keySet());
  65. map.put("k5", "v2");
  66. System.out.println("v2 -> " + map.getByValue("v2").keySet());
  67. map.put("k5", "v1");
  68. System.out.println("v1 -> " + map.getByValue("v1").keySet());
  69. System.out.println("v2 -> " + map.getByValue("v2").keySet());
  70. //替换所有的v1为v111
  71. System.out.println("before update : " + map);
  72. for(String k : map.getByValue("v1").keySet()) {
  73. map.put(k, "v111");
  74. }
  75. System.out.println("after update : " + map);
  76. }
  77. }
  78.  
  79.  
  80. //运行结果
  81.  
  82. k1 -> v1
  83. v1 -> [k3, k1]
  84. v2 -> [k4, k2]
  85. v2 -> [k5, k4, k2]
  86. v1 -> [k5, k3, k1]
  87. v2 -> [k4, k2]
  88. before update : {k3=v1, k4=v2, k5=v1, k1=v1, k2=v2}
  89. after update : {k3=v111, k4=v2, k5=v111, k1=v111, k2=v2}
  90.  

如果觉得本博客对您有帮助,请 赞助作者

转载请注明:lxw的大数据田地 » Java实现的双向Map,支持重复Value

喜欢 (1)
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址