LinkedHashMap 修改指定的Key值并且保持原有Key的顺序不变

需求:今天遇到一个数据处理的问题,我使用了LinkedHashMap集合统计数据,但是数据中出现了Key值相同的数据,因此想要把两个对象都保存起来并且不影响put的顺序。

方案1:首先查了一下LinkedHashMap类提供的方法,有修改指定Key对应的Value的,但是没找到修改Key值的(比较遗憾,不知道是自己没找到还是没提供,个人觉得这个功能挺有用的)

方案2:基于方案1,我想着那就创建一个新的LinkedHashMap对象并赋值给oldMap (oldMap = newMap),很奇怪,失败了,因为oldMap是通过引用传值方式(该方法还会返回其他数据)

方案3:基于方案2,我只能尝试将oldMap清空,然后遍历newMap向oldMap添加,结果终于成功了。

 

再次记录下方案1与方案2的代码:

 1 @Slf4j
 2 public class Main {
 3     public static void main(String[] args) {
 4 
 5         LinkedHashMap<String, Object> keyValueMap = new LinkedHashMap<>();
 6         keyValueMap.put("1", 1);
 7         keyValueMap.put("2", 2);
 8         keyValueMap.put("3", 3);
 9 
10         String newKey = "1";
11         Integer newObject = 4;
12 
13         newKey = addNewData(newKey, keyValueMap);
14 
15         keyValueMap.put(newKey, newObject);
16 
17         keyValueMap.entrySet().stream().forEach(entry -> log.info("key:{}, value:{}", entry.getKey(), entry.getValue()));
18     }
19 
20     private static String addNewData(String newKey, LinkedHashMap<String, Object> keyValueMap) {
21 
22         String nextKey = newKey;
23 
24         List<String> keyList = keyValueMap.keySet().stream().collect(Collectors.toList());
25 
26         if (keyList.contains(newKey)) {
27             Integer num = getKeyNum(keyList, newKey);
28 
29             LinkedHashMap<String, Object> map = replaceSpecifyKey(keyValueMap, newKey, new StringBuffer(newKey).append("_").append(++num).toString());
30 
31             // 方案1 start
32             keyValueMap = map;
33             // 方案1 end
34             
35             // 方案2 start
36             keyValueMap.clear();
37 
38             map.entrySet().stream().forEach(entry -> {
39                 keyValueMap.put(entry.getKey(), entry.getValue());
40             });
41             // 方案2 end
42 
43             nextKey = new StringBuffer(newKey).append("_").append(++num).toString();
44         }
45 
46         return nextKey;
47     }
48 
49     private static Integer getKeyNum(List<String> keyList, String newKey) {
50         AtomicReference<Integer> num = new AtomicReference<>(0);
51 
52         keyList.stream().forEach(key -> {
53             if (key.contains("_")) {
54                 num.set(Integer.parseInt(key.substring(key.lastIndexOf("_") + 1).trim()));
55             }
56         });
57 
58         return num.get();
59     }
60 
61     private static LinkedHashMap<String, Object> replaceSpecifyKey(LinkedHashMap<String, Object> keyValueMap, String specifyKey, String targetKey) {
62         LinkedHashMap<String, Object> newKeyValueMap = new LinkedHashMap<>();
63 
64         keyValueMap.entrySet().stream().forEach(entry -> {
65             if (specifyKey.equals(entry.getKey())) {
66                 newKeyValueMap.put(targetKey, entry.getValue());
67             } else {
68                 newKeyValueMap.put(entry.getKey(), entry.getValue());
69             }
70         });
71 
72         return newKeyValueMap;
73     }
74 }
View Code

 

结果:

  方案1:

      key:1, value:1
      key:2, value:2
      key:3, value:3
      key:1_2, value:4

 

  方案2:

      key:1_1, value:1
      key:2, value:2
      key:3, value:3
      key:1_2, value:4

 

结论:方案2的结果是我的期望,虽然方案1也可以同时保存数据,但是并不是我想要的。

也给我自己留一个TODO,方案1为什么不能成功,大家如果知道原因,也可以帮我解答下,至于此方案我觉得也非最优方案,如果有更优方案,也可分享给我和大家,谢谢各位!

 

posted @ 2022-07-08 01:00  hjjsunli  阅读(1654)  评论(0编辑  收藏  举报