英文:
How to sort a Hashmap<String, List<String>> according to the elements on the list? Java 8
问题
以下是您要翻译的内容:
I'm trying to sort this in natural order byKey and byValue using lambda expression and Stream Pipe line Java 8:
Map<String, List<String>> result = new HashMap<>();
So, the first part (sorting by natural order) is easy but I am having difficulty with the second part.
The sort should be done by the elements of the list`(List<String>)` and the result looks like:
input:
{E, [G,B,H]}
{C, [E,A,B]}
{A, [M,D,C]}
output:
{A, [C,D,M]}
{C, [A,B,E]}
{E, [B,G,H]}
The first part of the sort byKey is like:
result.entrySet().stream()
.sorted(Map.Entry.comparingByKey()).forEach(e -> {
System.out.println(e.getKey() + " " + e.getValue() );
});
But as I mentioned before I don't know how exactly do the next step:
result.entrySet().stream()
.sorted(Map.Entry.comparingByKey()
.thenComparing((e1,e2) -> e1.getValue().stream().sorted((s1,s2) -> s1.compareTo(s2)))
)
.forEach(e -> {
System.out.println(e.getKey() + " " + e.getValue() );
});
This lambda expression gave me some compile errors.
Also could you add sources to read about?
英文:
I'm trying to sort this in natural order byKey and byValue using lambda expression and Stream Pipe line Java 8:
Map<String, List<String>> result = new HashMap<>();
So, the first part (sorting by natural order) is easy but I am having difficulty with the second part.
The sort should be done by the elements of the list(List<String>)
and the result looks like:
input:
{E, [G,B,H]}
{C, [E,A,B]}
{A, [M,D,C]}
output:
{A, [C,D,M]}
{C, [A,B,E]}
{E, [B,G,H]}
The first part of the sort byKey is like:
result.entrySet().stream()
.sorted(Map.Entry.comparingByKey()).forEach(e -> {
System.out.println(e.getKey() + " " + e.getValue() );
});
But as I mentioned before I don't know how exactly do the next step:
result.entrySet().stream()
.sorted(Map.Entry.comparingByKey()
.thenComparing((e1,e2) -> e1.getValue().stream().sorted((s1,s2) -> s1.compareTo(s2)))
)
.forEach(e -> {
System.out.println(e.getKey() + " " + e.getValue() );
});
This lambda expression gave me some compile errors.
Also could you add sources to read about?
答案1
得分: 1
不能依赖键保持在结果映射中的排序顺序,因为映射本质上是无序的。它可能看起来可以工作,但这取决于键的哈希码和其他映射因素。但对于较大的映射,您不能依赖它。要解决这个问题,您可以指定一个TreeMap,它会维护键的排序顺序作为结果映射,然后使用streams
来对列表进行排序。
Map<String, List<String>> map = Map.of("E", List.of("G", "B", "H"), "C",
List.of("E", "A", "B"), "A", List of("M", "D", "C"));
Map<String, List<String>> result = map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().sorted().toList(),
(a,b)->a, // merge function here, not used but required
TreeMap::new));
result.entrySet().forEach(System.out::println);
打印结果如下:
A=[C, D, M]
C=[A, B, E]
E=[B, G, H]
与上面的方法的替代方案是基于键对Entry
进行排序,然后指定一个LinkedHashMap
。LinkedHashMap会保留插入顺序。除此之外,其他都与上面相同。
Map<String, List<String>> result2 = map.entrySet().stream()
.sorted(Entry.comparingByKey())
.collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().sorted().toList(),
(a,b)->a, // merge function here, not used but required
LinkedHashMap::new));
英文:
You cannot depend on the keys to remain in sorted order in the resulting map since maps are inherently unordered. It may appear to work but it depends on the hashCodes
of the keys and other map factors. But for larger maps you cannot depend on it. To solve this you can specify a TreeMap which maintains a sorted order for the keys as then resultant map and use streams
to sort the lists.
Map<String, List<String>> map = Map.of("E", List.of("G", "B", "H"), "C",
List.of("E", "A", "B"), "A", List.of("M", "D", "C"));
Map<String, List<String>> result = map.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().sorted().toList(),
(a,b)->a, // merge function here, not used but required
TreeMap::new));
result.entrySet().forEach(System.out::println);
prints
A=[C, D, M]
C=[A, B, E]
E=[B, G, H]
An alternative to the above is to sort the Entry
based on the key and the specify a LinkedHashMap
. LinkedHashMaps retain their insertion order. Everything else is the same as above.
Map<String, List<String>> result2 = map.entrySet().stream()
.sorted(Entry.comparingByKey())
.collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().sorted().toList(),
(a,b)->a, // merge function here, not used but required
LinkedHashMap::new));
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论