排序图< String,Integer>通过List< String>使用流 [英] Ordering Map<String, Integer> by List<String> using streams
问题描述
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 =新的HashMap<>();for(Map.Entry< String,Integer> nod:nonOrderedData.entrySet()){对于(String os:orderSequence){如果(os == nod.getKey()){//添加nonOrderedData数据} 别的 {//按顺序添加数据}}}
想对我想要的东西有更清洁的方式.
我已经注意到,在我的方法中,我可以只返回 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>重新排序= orderSequence.溪流().filter(nonOrderedData :: containsKey).collect(Collectors.toMap(键->键,nonOrderedData :: get,(v1,v2)->v1,LinkedHashMap :: new));System.out.println(已重新排序);
输出:
{a = 0,e = 4,o = 5,b = 1,d = 7}
类似于 orderSequence
和 nonOrderedData
之间的 INNER JOIN
.
- 如果
- 使用一些默认值填充
reorderedData
:
orderSequence
中的键在 nonOrderedData
中丢失,则 Map< String,Integer>reorderedWithDefault = orderSequence.溪流().collect(Collectors.toMap(键->键,nonOrderedData.getOrDefault(key,-1),(v1,v2)->v1,LinkedHashMap :: new));System.out.println(reorderedWithDefault);
输出:
{a = 0,e = 4,i = -1,o = 5,u = -1,b = 1,c = -1,d = 7}
类似于 orderSequence
和 nonOrderedData
之间的 LEFT JOIN
.
更新 输出: 类似于 此处将为 输出: I need to apply the order sequence to get correctly ordered data, how could I achieve this using (prefered) stream? What I used is non stream way: Would like to have more cleaner way of what I want. I've noticed that in my method I could just return The Ordering by the data presented in
Output: It is similar to
Output: It is similar to Update However, the following two code examples modify the state of
Output: It is similar to Here default values will be provided for the non-mapped keys in Output:
这篇关于排序图< String,Integer>通过List< String>使用流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
在上述实现中,完全跳过了 nonOrderedData
中与 orderSequence
中的键不匹配的键-值对.可以使用 Map< String,Integer>nonOrderedData =新的HashMap<>(Map.of("b",1,"e",4,"z",8,"a",0,"q",6"f",5,"d",7));List< String>orderSequence = Arrays.asList("a","e","i","o","u","b","c","d");Map< String,Integer>重新排序= orderSequence.溪流().filter(nonOrderedData :: containsKey).collect(Collectors.toMap(键->键,nonOrderedData :: remove,(v1,v2)->v1,LinkedHashMap :: new));SortedMap< String,Integer>剩余=新的TreeMap<>(nonOrderedData);System.out.println(剩余:" +余数);reordered.putAll(remainder);System.out.println(已重新排序);
保留:{f = 5,q = 6,z = 8}{a = 0,e = 4,b = 1,d = 7,f = 5,q = 6,z = 8}
orderSequence
和 nonOrderedData
之间的 RIGHT JOIN
. orderSequence
和 nonOrderedData
中的所有值,类似于 FULL JOIN
orderSequence
中的未映射键提供默认值,并将 nonOrderedData
中的不匹配键添加到末尾.
Map< String,Integer>reorderedFull = orderSequence.溪流().peek(key-> nonOrderedData.computeIfAbsent(key,(k)-> -1))//默认值.collect(Collectors.toMap(键->键,nonOrderedData :: remove,(v1,v2)->v1,LinkedHashMap :: new));SortedMap< String,Integer>restderFull =新的TreeMap<>(nonOrderedData);System.out.println(剩余:" +"remainderFull");reorderedFull.putAll(remainderFull);System.out.println(reorderedFull);
保留:{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}
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)
and it would work just fine, but I don't want to stick to just applying asc order - I would like to read actual sequence values and then change nonOrderedData
.HashMap
cannot be used to store orderedData
because it does not guarantee ordering of its keys, so LinkedHashMap
should be used which maintains insertion order.orderSequence
using streams may be implemented in two modes:
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}
INNER JOIN
between orderSequence
and nonOrderedData
.
reorderedData
with some default value if the key from orderSequence
is missing in 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);
{a=0, e=4, i=-1, o=5, u=-1, b=1, c=-1, d=7}
LEFT JOIN
between orderSequence
and nonOrderedData
.
In the above-mentioned implementations the key-value pairs in nonOrderedData
that do not match to the keys in orderSequence
are skipped altogether. Such keys may be tracked (and added later to the reordered
result) using Map::remove (Object key)
which returns a value of the key being removed.nonOrderedData
outside the stream execution.
nonOrderedData
, place the non-matched pairs to the end:Map<String, Integer> nonOrderedData = new HashMap<>(Map.of(
"b", 1, "e", 4, "z", 8, "a", 0, "q", 6,
"f", 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::remove,
(v1, v2) -> v1, LinkedHashMap::new
));
SortedMap<String, Integer> remainder = new TreeMap<>(nonOrderedData);
System.out.println("remained: " + remainder);
reordered.putAll(remainder);
System.out.println(reordered);
remained: {f=5, q=6, z=8}
{a=0, e=4, b=1, d=7, f=5, q=6, z=8}
RIGHT JOIN
between orderSequence
and nonOrderedData
.
orderSequence
and nonOrderedData
similar to FULL JOIN
orderSequence
and non-matched keys from nonOrderedData
will be added to the end.Map<String, Integer> reorderedFull = orderSequence
.stream()
.peek(key -> nonOrderedData.computeIfAbsent(key, (k) -> -1)) // default value
.collect(Collectors.toMap(
key -> key, nonOrderedData::remove,
(v1, v2) -> v1, LinkedHashMap::new
));
SortedMap<String, Integer> remainderFull = new TreeMap<>(nonOrderedData);
System.out.println("remained: " + remainderFull);
reorderedFull.putAll(remainderFull);
System.out.println(reorderedFull);
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}