根据嵌套地图的值对外部地图进行排序
Sort the outer map by the value of the nested map
按嵌套中的列表大小对外部映射Map<String, Map<String, List<Integer>>>
进行排序] 像以前一样保留外键和内键的地图。
您可以通过概括该过程来解决此问题:
private static <K,V,R> Map<K,R>
replaceAndSortValues(Map<K,V> m, Function<V,R> f, Comparator<R> c) {
return m.entrySet().stream()
.map(e -> Map.entry(e.getKey(), f.apply(e.getValue())))
.sorted(Map.Entry.comparingByValue(c.reversed()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a,b) -> { throw new AssertionError(); },
LinkedHashMap::new));
}
此方法使用与指定键相同的键创建一个新映射,使用指定函数替换所有值并根据指定比较器的反转对条目进行排序。它使用 Java 9 的 Map.entry(…, …)
工厂。如果您必须支持 Java 8 或 null
个键或值,您可以改用 new AbstractMap.SimpleImmutableEntry<>(…, …)
。
此方法现在可用于将内部地图的 List
替换为代表其大小的 Integer
并按降序排列,并将替换操作用作外部地图的替换功能:
public static Map<String, Map<String, Integer>>
getCallWithStateSizeGroup(ThreadDumpDo threadDumpDo) {
return replaceAndSortValues(getCallStackWithStateGroup(threadDumpDo),
m -> replaceAndSortValues(m, List::size, Comparator.<Integer>naturalOrder()),
Comparator.comparing(m -> m.values().iterator().next()));
}
这与您发布的解决方案基本相同。外层映射的比较器利用了新的内层映射已经排序的事实,所以它们的第一个值是最大值。但是一定不能有空的内图。
这很容易适应以保留 List<ThreadDo>
并按大小对它们进行排序:
public static Map<String, Map<String, List<ThreadDo>>>
getCallWithStateSizeGroup(ThreadDumpDo threadDumpDo) {
return replaceAndSortValues(getCallStackWithStateGroup(threadDumpDo),
m -> replaceAndSortValues(m, Function.identity(),
Comparator.comparingInt(List::size)),
Comparator.comparingInt(m -> m.values().iterator().next().size()));
}
我们只需要将内部映射的替换函数更改为 Function.identity()
并提供一个使用列表大小的比较器。 outer map 的比较器此时仍然可以利用 inner maps 已经排序的事实,但也必须提取列表的 size()
进行比较。
按嵌套中的列表大小对外部映射Map<String, Map<String, List<Integer>>>
进行排序] 像以前一样保留外键和内键的地图。
您可以通过概括该过程来解决此问题:
private static <K,V,R> Map<K,R>
replaceAndSortValues(Map<K,V> m, Function<V,R> f, Comparator<R> c) {
return m.entrySet().stream()
.map(e -> Map.entry(e.getKey(), f.apply(e.getValue())))
.sorted(Map.Entry.comparingByValue(c.reversed()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a,b) -> { throw new AssertionError(); },
LinkedHashMap::new));
}
此方法使用与指定键相同的键创建一个新映射,使用指定函数替换所有值并根据指定比较器的反转对条目进行排序。它使用 Java 9 的 Map.entry(…, …)
工厂。如果您必须支持 Java 8 或 null
个键或值,您可以改用 new AbstractMap.SimpleImmutableEntry<>(…, …)
。
此方法现在可用于将内部地图的 List
替换为代表其大小的 Integer
并按降序排列,并将替换操作用作外部地图的替换功能:
public static Map<String, Map<String, Integer>>
getCallWithStateSizeGroup(ThreadDumpDo threadDumpDo) {
return replaceAndSortValues(getCallStackWithStateGroup(threadDumpDo),
m -> replaceAndSortValues(m, List::size, Comparator.<Integer>naturalOrder()),
Comparator.comparing(m -> m.values().iterator().next()));
}
这与您发布的解决方案基本相同。外层映射的比较器利用了新的内层映射已经排序的事实,所以它们的第一个值是最大值。但是一定不能有空的内图。
这很容易适应以保留 List<ThreadDo>
并按大小对它们进行排序:
public static Map<String, Map<String, List<ThreadDo>>>
getCallWithStateSizeGroup(ThreadDumpDo threadDumpDo) {
return replaceAndSortValues(getCallStackWithStateGroup(threadDumpDo),
m -> replaceAndSortValues(m, Function.identity(),
Comparator.comparingInt(List::size)),
Comparator.comparingInt(m -> m.values().iterator().next().size()));
}
我们只需要将内部映射的替换函数更改为 Function.identity()
并提供一个使用列表大小的比较器。 outer map 的比较器此时仍然可以利用 inner maps 已经排序的事实,但也必须提取列表的 size()
进行比较。