[英]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 java-stream in this way.
我宁愿不以这种方式使用java-stream 。
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.