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 执行此类任务的提示。
谢谢
我找到了一个很容易阅读和使用的解决方案:
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()也没有检查的结果。在无状态行为部分阅读更多内容。我宁愿不以这种方式使用java-stream。
如果我是你,我会利用迭代器的优点:
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)