如何用 java 流重新组合树状图

How to regroup a treemap with java streams

我有一个 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);

输出:

{1=1, 2=2, 3=6, 4=9, 5=10, 8=10}

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

感谢

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

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)); 

.. 或更短感谢 @HadiJ:

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

...但它有一个显着的缺点:

我不能保证这会并行工作,因为它取决于 keyIterator.next() 的结果,该结果也未被检查。以这种方式在 Stateless Behaviors. I'd rather not use 部分阅读更多内容。


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

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
}

你的方法不错。您可以将其缩短为

PriorityQueue<Integer> q = new PriorityQueue<>(map.values());
map.entrySet().forEach(e -> e.setValue(q.remove()));

我认为此任务不适合 Stream API。