简体   繁体   English

Java Sort map by key说明

[英]Java Sort map by key explanation

I recently found a great way to sort a map that contains GregorianCalendar as keys. 最近,我找到了一种对包含GregorianCalendar作为键的地图进行排序的好方法。

Map<GregorianCalendar, String> map = new HashMap<>();

Map<GregorianCalendar, String> sortedMap = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
            (oldValue, newValue) -> oldValue, LinkedHashMap::new));

Can someone help me to understand each procedure called in this command especially going on from the stream function ? 有人可以帮助我理解此命令中调用的每个过程,尤其是从stream函数进行的过程吗?

Thanks 谢谢

map.entrySet().stream() produces a Stream of the entries of the input Map (ie a Stream<Map.Entry<GregorianCalendar,String>> . map.entrySet().stream()产生一个Stream的输入的条目的Map (即, Stream<Map.Entry<GregorianCalendar,String>>

.sorted(Map.Entry.comparingByKey()) sorts the elements of this Stream by the keys of the entries (it relies on the fact that the key type - GregorianCalendar - implements Comparable ). .sorted(Map.Entry.comparingByKey())通过条目的键对Stream的元素进行排序(它依赖于键类型GregorianCalendar实现Comparable的事实)。

.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new))

produces a LinkedHashMap that contains the same entries as the input Map . 产生一个LinkedHashMap ,其中包含与输入Map相同的条目。 Since you are using LinkedHashMap , the insertion order is maintained, and since you sorted the entries of the Stream by the keys, you get a Map whose insertion order (and iteration order) is according to the order of the keys. 由于您使用的是LinkedHashMap ,因此将保留插入顺序,并且由于按键对Stream的条目进行了排序,因此您将获得一个Map其插入顺序(和迭代顺序)是根据键的顺序排列的。

Of course you can get a sorted Map more easily by putting all the entries of the input Map in a TreeMap : 当然,通过将输入Map所有条目放在TreeMap可以更轻松地获得排序的Map

Map<GregorianCalendar, String> sortedMap = new TreeMap<>(map);

This has the advantage of maintaining the order even if you add new entries to the Map . 即使将新条目添加到Map这也可以保持顺序。

First you sort entries by Key via sorted(Map.Entry.comparingByKey()) 首先,您通过sorted(Map.Entry.comparingByKey())Key对条目进行sorted(Map.Entry.comparingByKey())

then these are are collected to a Map (the implementation underneath uses HashMap ), where the Key is of type GregorianCalendar and value is of type String . 然后将它们收集到Map (下面的实现使用HashMap )中,其中Key的类型为GregorianCalendar而value的类型为String The code also supplies a merge function: 该代码还提供了合并功能:

(oldValue, newValue) -> oldValue

where they keep the last value, when there is a collision, like a "last-wins" policy. 当发生冲突时,它们会保留最后的值,例如“最后获胜”策略。 So when these is a collision ( two same GregorianCalendar values ), you will always keep the second one, whatever second means here. 因此,当这些是冲突(两个相同的GregorianCalendar值)时,无论第二个在这里意味着什么,您都将始终保留第二个。 Since your source for streaming is a HashMap that does not have a defined order, this "second" can change if you have add or remove values from your initial map. 由于您的流媒体源是没有定义顺序的HashMap ,因此如果您在初始地图中添加或删除了值,则“秒”可以更改。

Once those are sorted and you collect them to a HashMap (via collect ), you order can break, so the collecting happens in a LinkedHashMap basically preserving that sorted order 对这些排序后,将它们收集到HashMap (通过collect ),您的订单可能会中断,因此收集发生在LinkedHashMap基本上保留了该排序顺序

I just want to leave a generic method for such sorting because it was a bit tricky for me 我只想为这种排序留一个通用方法,因为这对我来说有点棘手

private <K extends Comparable<? super K>,V> Map<K, V> sortMapByKey(Map<K, V> map) {

        return  map.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM