简体   繁体   English

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

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

I have this code in which I am overwriting values of Map from an ArrayList.我有这段代码,我在其中覆盖了 ArrayList 中 Map 的值。
I want to write this code using Streams and Lambda expression我想使用 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;
        }

Thank You!谢谢你!

You could convert the map keys to a list, and then loop through both map keys and sorted list simultaneously using IntStream:您可以将映射键转换为列表,然后使用 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);

This can be implemented in different ways:这可以通过不同的方式实现:

  1. Convert keySet of the sorted map into list and use indexes to build a map using Collectors.toMap :将已排序映射的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. Use AtomicInteger and its getAndIncrement when streaming by keys of the sorted map to refer the element in the list with the updates:在按排序映射的键流式传输时使用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. Similarly to previous implementation, current map may be modified using forEach of the map's entrySet() :与之前的实现类似,可以使用forEach地图的entrySet()修改当前地图:
AtomicInteger j = new AtomicInteger(0);
map.entrySet().forEach(e -> e.setValue(list.get(j.getAndIncrement())));

Extra safety measures may need to be added, for instance, handling of the case when the map and the list are of different size.可能需要添加额外的安全措施,例如处理地图和列表大小不同的情况。

These examples prove the feasibility of such task, though the task itself does not seem to be an appropriate application of Stream API.这些示例证明了此类任务的可行性,尽管任务本身似乎不是 Stream API 的合适应用。

Doing literally the same as your original code, ie set the values of the existing sortedMap in descending order, can be achieved as与原始代码完全相同,即按降序设置现有sortedMap的值,可以实现为

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

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

This assumes that the list and the map have the same size, as you acknowledged in a comment, ie it does not check for the end of the Iterator .这假设列表和地图具有相同的大小,正如您在评论中所承认的那样,即它不检查Iterator的结尾。

It's important that sortedMap truly has to be a SortedMap or a map implementation maintaining an order in general, which excludes the HashMap mentioned in the title of your question.重要的是sortedMap确实必须是SortedMap或通常维护顺序的地图实现,这不包括问题标题中提到的HashMap Otherwise, it's pointless to sort the values of the arrayList否则,对arrayList的值进行排序是没有意义的……

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

相关问题 Java 8: how to extract a HashMap from a ArrayList of HashMap in Java 8 using streams? - Java 8 : how to extract a HashMap from a ArrayList of HashMap in Java 8 using streams? 如何使用java流对作为HashMap值的ArrayList的元素求和? - How to sum elements of an ArrayList which are values of a HashMap using java streams? 如何从 Java 中的嵌套 HashMap 创建值的数组列表? - How do i create an arraylist of values from a nested HashMap in java? 使用流从hashmap中获取值的总和 - Sum of values from hashmap using streams 如何使用一对 object ZA2F2ED4F8EBC2CBB4C21A29DC40AB6 将 HashMap 中的值复制到 ArrayList - How to copy values from HashMap into an ArrayList using a Pair object class Java:如何将Comparator与arraylist一起用作HashMap的值 - Java: How to use Comparator with arraylist as values of HashMap Java ArrayList:从包含HashMap的ArrayList中获取不同的值 - Java ArrayList: Get Distinct Values from ArrayList which contain HashMap 通过使用 lambda 表达式和 Java 从 88677344588 的 ArrayList 中提取 HashMap 8 - Extract HashMap from an ArrayList of Hashmap by using lambda expression with Java 8 如何在java中使用hashmap查找ArrayList中的重复项? - how to find the duplicates in ArrayList using hashmap in java? 如何使用流从另一个 HashMap 填充一个 HashMap - How to fill a HashMap from another HashMap using streams
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM