java中对Map进行排序的方法

admin

java中经常排序,但是自己对Map的排序方法一直不是很清楚,特此记录。 Map作为键值对的存储工具,基本的概念介绍网上都有,自己参考如下博客:

https://www.cnblogs.com/chenssy/p/3264214.html

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

HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。TreeMap: 能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。

本文正文下面式排序方式的介绍:

Map的排序方式一 直接使用TreeMap进行排序

public class test {

public static void main(String[] args) {

Map map = new TreeMap<>();

map.put("a", "I'am a");

map.put("c", "I'am c");

map.put("d", "I'am d");

map.put("b", "I'am b");

for (Map.Entry entry : map.entrySet()) {

System.out.println(entry.getKey() + " " + entry.getValue());

}

}

}

输出的结果如下:

a I’am a b I’am b c I’am c d I’am d

但是上面的排序默认是按照Key值进行排序的,并且按照的是默认的升序排序,如果我们想改变默认的排序方式,即按照我们自己的比较方式排序,我们就需要实现自己的比较器,实现方式如下(下面的这种实现方式只能根据key值进行排序): 下面的代码实现了根据key值进行降序排序

public class test {

public static void main(String[] args) {

Map map = new TreeMap<>(new Comparator() {

@Override

public int compare(Integer o1, Integer o2) {

return o2 - o1;

}

});

// 上面的Map可也以写成lambda表达式的形式 Map map = //new TreeMap<>((o1, o2) -> o2 - o1);

map.put(3, "I'am 3");

map.put(0, "I'am 0");

map.put(2, "I'am 2");

map.put(1, "I'am 1");

for (Map.Entry entry : map.entrySet()) {

System.out.println(entry.getKey() + " " + entry.getValue());

}

}

}

输出: 3 I’am 3 2 I’am 2 1 I’am 1 0 I’am 0

以上的排序方法都是根据Key值进行排序,如果我们想根据value进行排序或者根据value和key进行排序,我们可以使用如下的方法

首先将map中的值转存到list中,然后对List进行排序,之后将list排序结果取出,再存储到LinkedHashMap中

public class test {

public static void main(String[] args) {

Map map = new HashMap<>();

map.put("I am d", "aaad");

map.put("I am c", "cs");

map.put("I am b", "baa");

map.put("I am a", "a");

List> list = new LinkedList<>(map.entrySet());

// 下面的也可以写成lambda表达式这种形式

// Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));

Collections.sort(list, new Comparator>() {

@Override

public int compare(Map.Entry o1, Map.Entry o2) {

return o2.getValue().compareTo(o1.getValue()); // 这里改为根据value值进降序排序,这里也可以改成根据key和value进行排序

}

});

Map result = new LinkedHashMap<>();

for (Map.Entry entry : list) {

result.put(entry.getKey(), entry.getValue());

}

System.out.println(result);

}

}

输出结果: {I am c=cs, I am b=baa, I am d=aaad, I am a=a} 这种自己平常不太使用,自己通常使用stream进行排序。

Map排序方法二:使用stream进行排序

Map map = new HashMap<>();

map.put(100, "I'am a");

map.put(99, "I'am c");

map.put(2, "I'am d");

map.put(33, "I'am b");

// 按照value进行倒排,如果要根据key进行排序的话使用Map.Entry.comparingByKey()

map.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))

.forEach(System.out::println);

// 根据value进行正序排序,根据key进行排序的话使用comparingByKey()

map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println);

// 如果要将排序的结果返回的话,我们可以使用下面的方法(注意:要使用LinkedHashMap进行保存,linkedHashMap可以保存插入顺序)

Map resultMap1 = map.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (s, s2) -> s,

LinkedHashMap::new));

// 下面的这种写法同上面的写法,只不过是将简写展开了,这样更易于理解

Map resultMap = map.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(new Function, Integer>() {

@Override

public Integer apply(Map.Entry integerStringEntry) {

return integerStringEntry.getKey();

}

}, new Function, String>() {

@Override

public String apply(Map.Entry integerStringEntry) {

return integerStringEntry.getValue();

}

}, new BinaryOperator() {

@Override

public String apply(String s, String s2) {

return s;

}

}, new Supplier>() {

@Override

public Map get() {

return new LinkedHashMap<>();

}

}));

// 同样如果需要将排序的将结果作为Map进行返回我们还可以使用下面的方法,但是不推荐这种方式(effectivejava 178页中说:foreach操作应该只用于报告stream计算的结果,而不是执行计算)

Map result2 = new LinkedHashMap<>();

map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(new Consumer>() {

@Override

public void accept(Map.Entry integerStringEntry) {

result2.put(integerStringEntry.getKey(), integerStringEntry.getValue());

}

});

https://www.jianshu.com/p/d20d2afbf87e

https://www.cnblogs.com/zimug/p/11781375.html https://blog.csdn.net/hao134838/article/details/80780622

Copyright © 2088 南美洲世界杯预选赛程_世界杯2 - ycfcjt.com All Rights Reserved.
友情链接