java中对Map进行排序的方法
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.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
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
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
// 上面的Map可也以写成lambda表达式的形式 Map
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
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.put("I am d", "aaad");
map.put("I am c", "cs");
map.put("I am b", "baa");
map.put("I am a", "a");
List
// 下面的也可以写成lambda表达式这种形式
// Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
Collections.sort(list, new Comparator
@Override
public int compare(Map.Entry
return o2.getValue().compareTo(o1.getValue()); // 这里改为根据value值进降序排序,这里也可以改成根据key和value进行排序
}
});
Map
for (Map.Entry
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.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
LinkedHashMap::new));
// 下面的这种写法同上面的写法,只不过是将简写展开了,这样更易于理解
Map
@Override
public Integer apply(Map.Entry
return integerStringEntry.getKey();
}
}, new Function
@Override
public String apply(Map.Entry
return integerStringEntry.getValue();
}
}, new BinaryOperator
@Override
public String apply(String s, String s2) {
return s;
}
}, new Supplier
@Override
public Map
return new LinkedHashMap<>();
}
}));
// 同样如果需要将排序的将结果作为Map进行返回我们还可以使用下面的方法,但是不推荐这种方式(effectivejava 178页中说:foreach操作应该只用于报告stream计算的结果,而不是执行计算)
Map
map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(new Consumer
@Override
public void accept(Map.Entry
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