简体   繁体   English

如何使用 java 流重新组合树形图

[英]How to regroup a treemap with java streams

I have a TreeMap<Integer, Integer> instance and I want to reassign the key value mappings in that way that the lowest key is assigned to the lowest value and the highest key to the highest key.我有一个TreeMap<Integer, Integer>实例,我想重新分配键值映射,将最低键分配给最低值,将最高键分配给最高键。

Here is how I do it without streams:这是我在没有流的情况下如何做到的:

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

output: output:

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

Any hints how to perform such a task utilizing java-8 Stream API are welcome.欢迎使用 java-8 Stream API 执行此类任务的任何提示。

Thx谢谢

I have found out a solution that is fairly easy to read and use:我找到了一个相当容易阅读和使用的解决方案:

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

.. or shorter thanks to @HadiJ : .. 或者更短,感谢@HadiJ

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

... but it has a significant drawback : ...但它有一个明显的缺点

I cannot guarantee this will work in parallel since it depends on the result of keyIterator.next() which is also not checked.我不能保证这将并行工作,因为它取决于keyIterator.next()的结果,该结果也未检查。 Read more at the section Stateless Behaviors .无状态行为部分阅读更多内容。 I'd rather not use in this way.我宁愿不以这种方式使用


If I were you, I'd use the advantage of the beauty of iterators:如果我是你,我会利用迭代器的优点:

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
}

Your approach is not bad.你的方法还不错。 You can shorten it to您可以将其缩短为

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

I don't think that this task is a good candidate for the Stream API.我不认为这个任务适合 Stream API。

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

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