使用流按List<String>对Map<String,Integer>进行排序
Map<String, Integer> nonOrderedData = // {b=1, c=2, d=3, e=4, a=0}
List<String> orderSequence = // a, b, c, d, e
我需要应用顺序序列来获取正确排序的数据,我如何使用(首选)流实现这一点?
我使用的是非流方式:
Map<String, Integer> orderedData = new HashMap<>();
for (Map.Entry<String, Integer> nod : nonOrderedData.entrySet()) {
for (String os : orderSequence) {
if (os == nod.getKey()) {
// add nonOrderedData data
} else {
// add data by sequence
}
}
}
想要更清洁的方式来实现我想要的。
我注意到在我的方法中我可以只返回new TreeMap<>(nonOrderedData)并且它会工作得很好,但我不想坚持只应用 asc 顺序 - 我想读取实际序列值然后更改nonOrderedData.
回答
将HashMap不能用于存储orderedData,因为它不保证其键的顺序,所以LinkedHashMap应使用哪个维护插入顺序。
通过orderSequence使用流中呈现的数据进行排序可以通过两种模式实现:
- 仅保留 中可用的值
nonOrderedData:
Map<String, Integer> nonOrderedData = Map.of(
"b", 1, "e", 4, "a", 0, "o", 5, "d", 7
);
List<String> orderSequence = Arrays.asList(
"a", "e", "i", "o", "u", "b", "c", "d"
);
Map<String, Integer> reordered = orderSequence
.stream()
.filter(nonOrderedData::containsKey)
.collect(Collectors.toMap(
key -> key, nonOrderedData::get,
(v1, v2) -> v1, LinkedHashMap::new
));
System.out.println(reordered);
输出:
{a=0, e=4, o=5, b=1, d=7}
{a=0, e=4, o=5, b=1, d=7}
它类似于INNER JOIN之间orderSequence和nonOrderedData。
reorderedData如果在orderSequence中缺少from 键,则填充一些默认值nonOrderedData:
输出:
{a=0, e=4, i=-1, o=5, u=-1, b=1, c=-1, d=7}
{a=0, e=4, i=-1, o=5, u=-1, b=1, c=-1, d=7}
它类似于LEFT JOIN之间orderSequence和nonOrderedData。
更新
在上述实现中nonOrderedData,与 中的键不匹配的键值对orderSequence被完全跳过。可以reordered使用Map::remove (Object key)返回要删除的键的值来跟踪此类键(并稍后添加到结果中)。
但是,以下两个代码示例修改nonOrderedData了流执行之外的状态。
- 保持键和相关的值只从
nonOrderedData,并将非配对到最后:
Map<String, Integer> reorderedWithDefault = orderSequence
.stream()
.collect(Collectors.toMap(
key -> key, nonOrderedData.getOrDefault(key, -1),
(v1, v2) -> v1, LinkedHashMap::new
));
System.out.println(reorderedWithDefault);
输出:
remained: {f=5, q=6, z=8}
{a=0, e=4, b=1, d=7, f=5, q=6, z=8}
它类似于RIGHT JOIN之间orderSequence和nonOrderedData。
- 保留两者的所有值
orderSequence并且nonOrderedData类似于FULL JOIN
这里将为未映射的键提供默认值 inorderSequence和不匹配的键 fromnonOrderedData将添加到末尾。
输出:
remained: {f=5, q=6, z=8}
{a=0, e=4, i=-1, o=-1, u=-1, b=1, c=-1, d=7, f=5, q=6, z=8}
THE END
二维码