Bootstrap

又双叒叕一行代码:Map按值排序

一文中,我将流量模型统计成为一个个形式数据保存起来。

由于本身是无序的,我希望能够按照各个流量模型的值进行排序输出,所以我又开始了学习的短暂旅途。

没想到除了以外,又发现了一行代码。

LinkedHashMap

我自己最常用的。HashMap是一种非常常见、非常有用的集合,但在多线程情况下使用不当会有线程安全问题。

所以通常情况下只要不涉及线程安全问题,基本都可以使用HashMap,不过本身是一个无序的,不会记录每一个数据插入的次序。

就闪亮登场了,它虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,保证了元素迭代的顺序。

基础写法

这是一个比较基础的写法,思路是先将转换成数据,然后使用方法进行排序,然后重新添加到集合对象当中。


public class Map_FunTester extends SourceCode {

    public static void main(String[] args) {
        Map hashMap = new HashMap<>();
        hashMap.put("fun", 3);
        hashMap.put("funtest", 7);
        hashMap.put("funtester", 9);
        hashMap.put("f", 1);
        output(hashMap);
        List> list = new ArrayList>(hashMap.entrySet());
        Collections.sort(list, new Comparator>() {
            public int compare(Map.Entry o1, Map.Entry o2) {
                return o1.getValue() - o2.getValue();
            }
        });
        Map linkedHashMap = new LinkedHashMap<>();
        for (Map.Entry entry : list) {
            linkedHashMap.put(entry.getKey(), entry.getValue());
        }
        output(linkedHashMap);
    }

}

控制台输出:

INFO-> 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> 
+-----------+---+
|     f     | 1 |
|  funtest  | 7 |
| funtester | 9 |
|    fun    | 3 |
+-----------+---+
INFO-> 
+-----------+---+
|     f     | 1 |
|    fun    | 3 |
|  funtest  | 7 |
| funtester | 9 |
+-----------+---+

Process finished with exit code 0

Lambda写法

其实这个功能完全可以使用写法来简化整个过程。如下:

        LinkedHashMap linkedHashMap = hashMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1 + v2, LinkedHashMap::new));
        output(linkedHashMap);

哈哈,又是一行代码创造的奇迹。

这个写法的重点就在于,有三个重载方法:

toMap(Function keyMapper, Function valueMapper);
toMap(Function keyMapper, Function valueMapper,
        BinaryOperator mergeFunction);
toMap(Function keyMapper, Function valueMapper,
        BinaryOperator mergeFunction, Supplier mapSupplier);

其中四个参数解释如下:

虽然从获取的时候不会出现重复,但是最后一个参数是,必须使用这个构造方法。

控制台输出:

如上

适用拓展

最常用的地方还说将转换成数据常用。例子如下:

    public static void main(String[] args) {
        List list = Arrays.asList("f", "fun", "funtest", "funtester");
        Map collect = list.stream().collect(Collectors.toMap(f -> f, f -> f.length(), (v1, v2) -> v2));
        output(collect);
    }

控制台输出:

INFO-> 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> 
+-----------+---+
|     f     | 1 |
|  funtest  | 7 |
| funtester | 9 |
|    fun    | 3 |
+-----------+---+

Process finished with exit code 0

Have Fun ~ Tester !

FunTester,非著名测试开发,欢迎关注。

点击阅读阅文,查看FunTester历史原创集合