我有这样的代码,其中我将覆盖ArrayList中Map的值
我想使用Streams和Lambda表达式编写此代码
List<Integer> list = new ArrayList<Integer>(arrayList);
Collections.sort(list, Collections.reverseOrder());
int i = 0;
Iterator<Entry<Integer, Integer>> itr = sortedMap.entrySet().iterator();
while(itr.hasNext()) {
Entry<Integer, Integer> pair = itr.next();
pair.setValue(list.get(i));
++i;
}
谢谢!
您可以将映射键转换为列表,然后使用IntStream同时循环通过映射键和排序列表:
List<Integer> list = new ArrayList<>(arrayList);
Collections.sort(list, Collections.reverseOrder());
List<Integer> mapKeys = new ArrayList<>(sortedMap.keySet());
Map<Integer,Integer> overwrittenMap =
IntStream.range(0,mapKeys.size())
.boxed()
.collect(TreeMap::new,
(map,i) -> map.put(mapKeys.get(i),list.get(i)),
Map::putAll);
与原始代码完全相同,即按降序设置现有sortedMap
的值,可以作为实现
Iterator<Integer> values = arrayList.stream()
.sorted(Collections.reverseOrder())
.iterator();
sortedMap.replaceAll((key,value) -> values.next());
这假设列表和映射具有相同的大小,正如您在注释中确认的那样,即它不检查Iterator
的末尾。
重要的是,sortedMap
必须是一个SortedMap
或一个维护订单的映射实现,这不包括问题标题中提到的HashMap
。否则,对arrayList
…的值进行排序是毫无意义的
这可以通过不同的方式实现:
- 将已排序映射的
keySet
转换为列表,并使用索引使用Collectors.toMap
构建映射:
List<Integer> keys = new ArrayList<>(map.keySet());
Map<Integer, Integer> res = IntStream
.range(0, list.size())
.boxed()
.collect(Collectors.toMap(i -> keys.get(i), i -> list.get(i), (a, b)-> a, TreeMap::new));
System.out.println(res);
- 当按排序映射的键进行流式传输时,使用
AtomicInteger
及其getAndIncrement
来引用列表中的更新元素:
AtomicInteger i = new AtomicInteger(0);
Map<Integer, Integer> res2 = map.keySet()
.stream()
.collect(Collectors.toMap(
k -> k,
k -> list.get(i.getAndIncrement()),
(a, b) -> a,
TreeMap::new // or LinkedHashMap::new as keys are sorted
));
System.out.println(res2);
- 与以前的实现类似,可以使用映射的
entrySet()
的forEach
修改当前映射:
AtomicInteger j = new AtomicInteger(0);
map.entrySet().forEach(e -> e.setValue(list.get(j.getAndIncrement())));
可能需要添加额外的安全措施,例如,当地图和列表大小不同时,处理案例。
这些例子证明了这种任务的可行性,尽管任务本身似乎不是Stream API的适当应用。