繁体   English   中英

如何使用 Java 8 Streams 从 ArrayList 覆盖 HashMap 的值

[英]How to overwrite values of HashMap from ArrayList using Java 8 Streams

我有这段代码,我在其中覆盖了 ArrayList 中 Map 的值。
我想使用 Streams 和 Lambda 表达式编写此代码

List<Integer> list = new ArrayList<Integer>(arrayList);
        
        Collections.sort(list, Collections.reverseOrder());

        int i = 0;
        Iterator<Entry<Integer, Integer>> itr = sortedMap.entrySet().iterator();
        while(itr.hasNext()) {
            Entry<Integer, Integer> pair = itr.next();
            pair.setValue(list.get(i));
            ++i;
        }

谢谢你!

您可以将映射键转换为列表,然后使用 IntStream 同时循环遍历映射键和排序列表:

List<Integer> list = new ArrayList<>(arrayList);
Collections.sort(list, Collections.reverseOrder());

List<Integer> mapKeys = new ArrayList<>(sortedMap.keySet());

Map<Integer,Integer> overwrittenMap = 
            IntStream.range(0,mapKeys.size())
                     .boxed()
                     .collect(TreeMap::new, 
                             (map,i) -> map.put(mapKeys.get(i),list.get(i)),
                             Map::putAll);

这可以通过不同的方式实现:

  1. 将已排序映射的keySet转换为列表,并使用Collectors.toMap使用索引构建映射:
List<Integer> keys = new ArrayList<>(map.keySet());
Map<Integer, Integer> res = IntStream
        .range(0, list.size())
        .boxed()
        .collect(Collectors.toMap(i -> keys.get(i), i -> list.get(i), (a, b)-> a, TreeMap::new));
System.out.println(res);
  1. 在按排序映射的键流式传输时使用AtomicInteger及其getAndIncrement以引用列表中的元素进行更新:
AtomicInteger i = new AtomicInteger(0);
Map<Integer, Integer> res2 = map.keySet()
                                .stream()
                                .collect(Collectors.toMap(
                                    k -> k, 
                                    k -> list.get(i.getAndIncrement()), 
                                    (a, b) -> a, 
                                    TreeMap::new // or LinkedHashMap::new as keys are sorted
                                ));
System.out.println(res2);
  1. 与之前的实现类似,可以使用forEach地图的entrySet()修改当前地图:
AtomicInteger j = new AtomicInteger(0);
map.entrySet().forEach(e -> e.setValue(list.get(j.getAndIncrement())));

可能需要添加额外的安全措施,例如处理地图和列表大小不同的情况。

这些示例证明了此类任务的可行性,尽管任务本身似乎不是 Stream API 的合适应用。

与原始代码完全相同,即按降序设置现有sortedMap的值,可以实现为

Iterator<Integer> values = arrayList.stream()
        .sorted(Collections.reverseOrder())
        .iterator();

sortedMap.replaceAll((key,value) -> values.next());

这假设列表和地图具有相同的大小,正如您在评论中所承认的那样,即它不检查Iterator的结尾。

重要的是sortedMap确实必须是SortedMap或通常维护顺序的地图实现,这不包括问题标题中提到的HashMap 否则,对arrayList的值进行排序是没有意义的……

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM