如何使用 Java 流重新组合树状图

per*_*ero 4 java treemap java-8 java-stream

我有一个TreeMap<Integer, Integer>实例,我想以最低键分配给最低值和最高键分配给最高键的方式重新分配键值映射。

这是我在没有流的情况下如何做到的:

 TreeMap<Integer, Integer> map = new TreeMap<>();
 map.put(1, 6);
 map.put(2, 9);
 map.put(4, 2);
 map.put(3, 1);
 map.put(8, 10);
 map.put(5, 10);

 ArrayList<Integer> valueList = new ArrayList<Integer>(map.values());
 Collections.sort(valueList);

 int i = 0;
 for (Map.Entry entry : map.entrySet()) {
      entry.setValue(valueList.get(i++));
 }

 System.out.println(map);
Run Code Online (Sandbox Code Playgroud)

输出:

{1=1, 2=2, 3=6, 4=9, 5=10, 8=10}
Run Code Online (Sandbox Code Playgroud)

欢迎任何有关如何使用 java-8 Stream API 执行此类任务的提示。

谢谢

Nik*_*las 5

我找到了一个很容易阅读和使用的解决方案:

Iterator<Integer> keyIterator = map.keySet().iterator();
TreeMap<Integer, Integer> newMap = map.values().stream()
    .sorted()
    .map(value -> new SimpleEntry<>(keyIterator.next(), value))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (l, r) -> l, TreeMap::new)); 
Run Code Online (Sandbox Code Playgroud)

.. 或者更短,感谢@HadiJ

map.values().stream()
            .sorted()
            .collect(Collectors.toMap(k -> keyIterator.next(),  Function.identity(), (l, r) -> l, TreeMap::new));
Run Code Online (Sandbox Code Playgroud)

...但它有一个明显的缺点

我不能保证这会并行工作,因为它取决于keyIterator.next()也没有检查的结果。在无状态行为部分阅读更多内容。我宁愿不以这种方式使用


如果我是你,我会利用迭代器的优点:

Iterator<Integer> values = valueList.iterator();
Iterator<Integer> keys = map.keySet().iterator();

TreeMap<Integer, Integer> newMap = new TreeMap<>();   // create a new Map
while (values.hasNext() && keys.hasNext()) {          // iterate simultaneously
    newMap.put(keys.next(), values.next());           // put the key-value
}
Run Code Online (Sandbox Code Playgroud)

  • 简化一下`map.values().stream() .sorted() .collect(Collectors.toMap(k-&gt;keyIterator.next(), Function.identity(), (l, r) -&gt; l, TreeMap: :新));` (3认同)
  • @HadiJ:是的,映射可以发生在收集器内部。如果您不介意的话,我已经编辑了我的答案并引用您。 (3认同)
  • @pero_hero,我想这是不可能的。这是另一种方式:`Map&lt;Integer,Integer&gt; reMap = map.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap(k-&gt;map.pollFirstEntry(). getKey(), Map.Entry::getValue,(a,b)-&gt;a,LinkedHashMap::new) );` (2认同)