一、简单介绍Map

在讲解Map排序之前,我们先来稍微了解下map,map是键值对的集合接口,它的实现类主要包括:HashMap, TreeMap, Hashtable以及LinkedHashMap等。其中这四者的区别如下(简单介绍):

HashMap:我们最常用的Map,HashMap是无序的,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。

TreeMap:能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。

Hashtable:与HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable, 因此也导致了Hashtale在写入时会比较慢。

LinkedHashMap:LinkedHashMap是有序的,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。

二、Map排序

java8新特性:对map集合排序,根据key或者value操作排序(升序、降序)

package com.drew.test;

import java.util.List;
import java.util.Map; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; /**
* @author zero 2019/04/08
*/
public class Java8future { public static void main(String[] args) {
Map<String, Integer> map = ImmutableMap.of("", , "", , "0.29", , "1.67", );
System.out.println("原始的map:" + map);
System.out.println("根据map的key降序:" + sortByKey(map, true));
System.out.println("根据map的key升序:" + sortByKey(map, false));
System.out.println("根据map的value降序:" + sortByValue(map, true));
System.out.println("根据map的value升序:" + sortByValue(map, false));
} /**
* 根据map的key排序
*
* @param map 待排序的map
* @param isDesc 是否降序,true:降序,false:升序
* @return 排序好的map
* @author zero 2019/04/08
*/
public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
Map<K, V> result = Maps.newLinkedHashMap();
if (isDesc) {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
} else {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
}
return result;
} /**
* 根据map的value排序
*
* @param map 待排序的map
* @param isDesc 是否降序,true:降序,false:升序
* @return 排序好的map
* @author zero 2019/04/08
*/
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean isDesc) {
Map<K, V> result = Maps.newLinkedHashMap();
if (isDesc) {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue().reversed())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
} else {
map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue())
.forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
}
return result;
}
}

HashMap

我们知道HashMap的值是没有顺序的,他是按照key的HashCode来实现的。对于这个无序的HashMap我们要怎么来实现排序呢?参照TreeMap的value排序,我们一样的也可以实现HashMap的排序。

public class HashMapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("c", "ccccc");
map.put("a", "aaaaa");
map.put("b", "bbbbb");
map.put("d", "ddddd");

//这里将map.entrySet转换为List
List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet());
//然后通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<String,String>>() {
//升序排序
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
}); for(Map.Entry<String,String> mapping:list){
System.out.println(mapping.getKey()+":"+mapping.getValue());
}
}
}
运行结果如下:
d:ddddd
c:ccccc
b:bbbbb
a:aaaaa

TreeMap

TreeMap默认是升序的,如果我们需要改变排序方式,则需要使用比较器:Comparator

Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,该方法主要是根据第一个参数o1小于、等于或者大于o2分别返回负整数、0或者正整数。代码如下:

public class TreeMapTest {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>(
new Comparator<String>() {
public int compare(String obj1, String obj2) {
// 降序排序
return obj2.compareTo(obj1);
}
});
map.put("c", "ccccc");
map.put("a", "aaaaa");
map.put("b", "bbbbb");
map.put("d", "ddddd"); Set<String> keySet = map.keySet();
Iterator<String> iter = keySet.iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println(key + ":" + map.get(key));
}
}
}
运行结果如下:
d:ddddd
c:ccccc
b:bbbbb
a:aaaaa

上面例子是根据TreeMap的key值来进行排序的,但是有时我们需要根据TreeMap的value来进行排序。对value排序我们就需要 借助于Collections的sort(List<T> list, Comparator<? super T> c)方法,该方法根据指定比较器产生的顺序对指定列表进行排序。

但是有一个前提条件,那就是所有的元素都必须能够根据所提供的比较器来进行比较。如下:

public class TreeMapTest {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>();
map.put("d", "ddddd");
map.put("b", "bbbbb");
map.put("a", "aaaaa");
map.put("c", "ccccc"); //这里将map.entrySet()转换成list
List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet());
//然后通过比较器来实现排序
Collections.sort(list, new Comparator<Map.Entry<String,String>>() {
//升序排序
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
for(Map.Entry<String,String> mapping:list) {
System.out.println(mapping.getKey()+":"+mapping.getValue());
}
}
}
运行结果如下:
d:ddddd
c:ccccc
b:bbbbb
a:aaaaa

java8新特性:对map集合排序的更多相关文章

  1. Java8 新特性 Streams map() 示例

    在Java 8中stream().map(),您可以将对象转换为其他对象.查看以下示例: 1.大写字符串列表 1.1简单的Java示例将Strings列表转换为大写. TestJava8.java p ...

  2. java8 新特性 Stream流 分组 排序 过滤 多条件去重

    private static List<User> list = new ArrayList<User>(); public static void main(String[] ...

  3. Java8新特性Stream流应用示例

    Java8新特性介绍 过滤集合 List<String> newList = list.stream().filter(item -> item != null).collect(C ...

  4. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  5. Java8 新特性之集合操作Stream

    Java8 新特性之集合操作Stream Stream简介 Java 8引入了全新的Stream API.这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同 ...

  6. [Java8教程]Java8新特性进阶集合

    Java8新特性进阶集合 基于 AOP 抽离方法的重复代码 Java8:当 Lambda 遇上受检异常 Java8:对字符串连接的改进 Java8:Java8 中 Map 接口的新方法 Java8:当 ...

  7. Java8新特性

    Java8新特性 Java8主要的新特性涵盖:函数式接口.Lambda 表达式.集合的流式操作.注解的更新.安全性的增强.IO\NIO 的改进.完善的全球化功能等. 1.函数式接口 Java 8 引入 ...

  8. 这可能是史上最好的 Java8 新特性 Stream 流教程

    本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...

  9. 干货 | Java8 新特性教程

    本教程翻译整理自 https://github.com/winterbe/java8-tutorial 本教程首发自个人网站: https://www.exception.site/java8/jav ...

随机推荐

  1. Python开发应用-正则表达进行排序搜索

    re模块提供了3个方法对输入的字符串进行确切的查询,match和search最多只会返回一个匹配条件的子串,可以理解为非贪婪模式,而findall会返回N个匹配条件的子串,可以理解为贪婪模式 re.m ...

  2. windows查看端口被占用情况

    首先,使用cmd命令打开CMD命令窗口 使用下面的命令来查看某端口被占用的情况,以8035为例: netstat -ano|findstr " 结果如下图: 最后一列的6532为PID号,根 ...

  3. hdu4767 Bell——求第n项贝尔数

    题意 设第 $n$ 个Bell数为 $B_n$,求 $B_n \ mod  \ 95041567$.($1 \leq  n  \leq  2^{31}$) 分析 贝尔数的概念和性质,维基百科上有,这里 ...

  4. LeetCode 740. Delete and Earn

    原题链接在这里:https://leetcode.com/problems/delete-and-earn/ 题目: Given an array nums of integers, you can ...

  5. 事件类型(onfocus和onblur)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Mycat 全局系列号(转载)

    概述 本篇文章介绍mycat怎样在分库分表的情况下保证主键的全局唯一方法,接下来就来分析三种方法各自的优缺点. 配置 文件方式获取 1.修改server配置文件 vim server.xml < ...

  7. 使用if和switch制作简单的年龄生肖判断

    -年 查询 --> var oDiv =document.getElementById("cont"); var oYear = document.getElementByI ...

  8. dbt 0.13.0 新添加特性sources 试用

    dbt 0.13 添加了一个新的功能sources 我呢可以用来做以下事情 从基础模型的源表中进行数据选择 测试对于源数据的假设 计算源数据的freshness source 操作 定义source ...

  9. Generating a Random Sample from discrete probability distribution

    If is a discrete random variable taking on values , then we can write . Implementation of this formu ...

  10. 【loj2567】【APIO2016】划艇

    题目 \(N\)个位置,每个位置要么不选,要么选\([ a_i, b_i ]\)中的一个数: 问最后的单调上升序列(mod 1e9+7)有多少种: \(1 \le N \le 500\) 题解 orz ...