=Start=
缘由:
Java中HashMap的值是没有顺序的,它是按照key的HashCode来实现的。对于这个无序的HashMap我们要怎么来实现排序呢?这里就整理总结一下,方便以后查阅、参考。
正文:
参考解答:
先说结论,如果着急的话可以先看这个/只看这个就够:
Java中对 HashMap 进行排序的一般步骤就是:
1、先根据 HashMap 的内容生成 list ;
2、再调用 Collections.sort(list[, new Comparator]) 对 list 进行就地排序;
2.1、 内部进行的比较一般是通过 .compareTo() 方法进行的,但是也可以自行修改「大于返回1,小于返回-1,等于返回0」;
3、 如果只要排序后的结果的话,可以直接用 list ;如果还要一个map的话,就新建一个LinkedHashMap来存放list的结果。
Java中的原生排序方法整理:
- 对基本类型排序 # Arrays.sort()
- 对对象数组排序 # 则要自己实现 java.util.Comparator 接口
//1. 数字排序 int[] intArray = new int[] { 4, 1, 3, -23 }; Arrays.sort(intArray); System.out.println(Arrays.toString(intArray)); //输出: [-23, 1, 3, 4] //2. 字符串排序,先大写后小写 String[] strArray = new String[] { "z", "a", "C" }; System.out.println(Arrays.toString(strArray)); //输出: [z, a, C] Arrays.sort(strArray); System.out.println(Arrays.toString(strArray)); //输出: [C, a, z] //3. 严格按字母表顺序排序,也就是忽略大小写排序 Case-insensitive sort Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); System.out.println(Arrays.toString(strArray)); //输出: [a, C, z] //4. 反向排序, Reverse-order sort Arrays.sort(strArray, Collections.reverseOrder()); System.out.println(Arrays.toString(strArray)); //输出: [z, a, C] //5. 忽略大小写反向排序 Case-insensitive reverse-order sort Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); Collections.reverse(Arrays.asList(strArray)); System.out.println(Arrays.toString(strArray)); //输出: [z, C, a]
Java中打印数组的方法,参考「链接」。
再放整理后的代码:
package com.ixyzero.learn.misc; import java.util.*; import java.util.Map.Entry; /** * https://stackoverflow.com/questions/8119366/sorting-hashmap-by-values/13913206#13913206 */ public class SortMapByValue { public static boolean ASC = true; public static boolean DESC = false; public static void main(String[] args) { // Creating dummy unsorted map Map<String, Integer> unsortedMap = new HashMap<>(); unsortedMap.put("B", 55); unsortedMap.put("A", 80); unsortedMap.put("D", 20); unsortedMap.put("C", 70); System.out.println("Before sorting......"); printMap(unsortedMap); System.out.println("\nAfter sorting ascending order......"); Map<String, Integer> sortedMapAsc = sortByValueComparator(unsortedMap, ASC); printMap(sortedMapAsc); System.out.println("\nAfter sorting descending order......"); Map<String, Integer> sortedMapDesc = sortByValueComparator(unsortedMap, DESC); printMap(sortedMapDesc); System.out.println("\nAfter sorting descending order by key......"); Map<String, Integer> sortedKeyMapDesc = sortByKeyComparator(sortedMapAsc, DESC); printMap(sortedKeyMapDesc); } private static Map<String, Integer> sortByKeyComparator(Map<String, Integer> unsortedMap, final boolean order) { List<Map.Entry<String, Integer>> list = new LinkedList<>(unsortedMap.entrySet()); // Sorting the list based on values Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { if (order) { return o1.getKey().toString().compareTo(o2.getKey().toString()); } else { return o2.getKey().toString().compareTo(o1.getKey().toString()); } } }); // Maintaining insertion order with the help of LinkedList Map<String, Integer> sortedMap = new LinkedHashMap<>(); for (Map.Entry<String, Integer> entry : list) { sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } private static Map<String, Integer> sortByValueComparator(Map<String, Integer> unsortedMap, final boolean order) { List<Map.Entry<String, Integer>> list = new LinkedList<>(unsortedMap.entrySet()); // Sorting the list based on values Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { if (order) { return o1.getValue().compareTo(o2.getValue()); } else { return o2.getValue().compareTo(o1.getValue()); } } }); // Maintaining insertion order with the help of LinkedList Map<String, Integer> sortedMap = new LinkedHashMap<>(); for (Map.Entry<String, Integer> entry : list) { sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } public static void printMap(Map<String, Integer> map) { for (Entry<String, Integer> entry : map.entrySet()) { System.out.println("Key: " + entry.getKey() + "\tValue: "+ entry.getValue()); } } }
参考链接:
- Java中对HashMap进行排序
- https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values
- https://stackoverflow.com/questions/8119366/sorting-hashmap-by-values/13913206#13913206
- Java原生排序方法总结–HashMap排序
- java对HashMap中的key或者value值进行排序!
- [Java]HashMap的两种排序方式
- https://blog.csdn.net/xifeijian/article/details/46522531
- Java中Hashmap按key排序
- HashMap遍历与按key排序。
=END=
《 “Java中如何对HashMap进行排序” 》 有 16 条评论
java集合遍历的几种方式总结及比较
https://www.cnblogs.com/leskang/p/6031282.html
`
集合类的通用遍历方式,用迭代器迭代:
Iterator it = list.iterator();
while(it.hasNext()) {
Object obj = it.next();
}
Map的几种遍历方式
List的几种遍历方式
数据元素是怎样在内存中存放的?
每个遍历方法的实现原理是什么?
各遍历方式对于不同的存储方式,性能如何?
各遍历方式的适用于什么场合?
Java的最佳实践是什么?
if (list instanceof RandomAccess) {
//使用传统的for循环遍历。
} else {
//使用Iterator或者foreach。
}
`
jdk HashMap工作原理分析
http://fangjian0423.github.io/2016/03/29/jdk_hashmap/
jdk LinkedHashMap工作原理分析
http://fangjian0423.github.io/2016/03/29/jdk_linkedhashmap/
jdk TreeMap工作原理分析
http://fangjian0423.github.io/2016/04/07/jdk_treemap/
fastjson将json字符串转化成map的五种方法
https://blog.csdn.net/sinat_29774479/article/details/78730359
java 两个map对象的合并成一个map对象
https://blog.csdn.net/lolashe/article/details/8785111
Java中如何把一下字符串转换成map
https://www.cnblogs.com/zhaoyan001/p/6108370.html
java中string类型转换成map
https://www.cnblogs.com/chongyou/p/7466039.html
Java中如何打印 byte[]
https://stackoverflow.com/questions/6463580/how-to-print-the-data-in-byte-array-as-characters/6463665#6463665
`
byte[] byteArray = new byte[] { -1, -128, 1, 127 };
System.out.println(Arrays.toString(byteArray));
`
Java中打印数组的最简单方法
https://stackoverflow.com/questions/409784/whats-the-simplest-way-to-print-a-java-array
`
# 简单数组(各种类型都可以,比如 int/double/String/byte)
String[] array = new String[] {“John”, “Mary”, “Bob”};
System.out.println(Arrays.toString(array));
# 嵌套数组
String[][] deepArray = new String[][] {{“John”, “Mary”}, {“Alice”, “Bob”}};
System.out.println(Arrays.toString(deepArray));
// output: [[Ljava.lang.String;@106d69c, [Ljava.lang.String;@52e922]
System.out.println(Arrays.deepToString(deepArray));
// [[John, Mary], [Alice, Bob]]
`
JAVA构造MAP并初始化MAP
https://stackoverflow.com/questions/6802483/how-to-directly-initialize-a-hashmap-in-a-literal-way
https://stackoverflow.com/questions/507602/how-can-i-initialise-a-static-map
https://blog.csdn.net/dujianxiong/article/details/54849079
`
方法一:先 new 创建,然后逐步 put 填充
Map myMap = new HashMap();
myMap.put(“a”, “b”);
myMap.put(“c”, “d”);
方法二:双括号初始化(匿名内部类)
Map map = new HashMap() {
{
put(“name”, “test”);
put(“age”, “20”);
}
};
`
Java中利用HashMap做去重计数
https://www.mkyong.com/java/how-to-count-duplicated-items-in-java-list/
`
Map map = new HashMap();
for (String temp : list) {
Integer count = map.get(temp);
map.put(temp, (count == null) ? 1 : count + 1);
}
`
Java program to count the occurrence of each character in a string using Hashmap
https://www.geeksforgeeks.org/java-program-to-count-the-occurrence-of-each-character-in-a-string-using-hashmap/
Map统计去重复统计重复出现的次数
https://blog.csdn.net/qq_40195958/article/details/78904634
java Map集合嵌套,value为Map和value为List
https://blog.csdn.net/mustbehard/article/details/17310043
`
Map<String,Map> outMap = new HashMap<String,Map>();
Map innerMap1 = new HashMap();
Map innerMap2 = new HashMap();
/*
* 要使用下面这种方式,先把集合定义好,
* 把映射关系设置好,再去给集合添加元素
*/
outMap.put(“map1”, innerMap1);
outMap.put(“map2”, innerMap2);
innerMap1.put(“01”, “zhangsan”);
innerMap1.put(“02”, “lisi”);
innerMap2.put(“01”, “zhaoliu”);
innerMap2.put(“02”, “zhouqi”);
`
java中HashMap的嵌套用例
https://blog.csdn.net/euller/article/details/70233062
Java以更好的格式打印map中的内容
https://stackoverflow.com/questions/10120273/pretty-print-a-map-in-java
https://stackoverflow.com/questions/15171699/multi-line-pretty-printing-of-nested-collections-in-java
https://commons.apache.org/proper/commons-collections/javadocs/api-4.2/org/apache/commons/collections4/MapUtils.html#debugPrint-java.io.PrintStream-java.lang.Object-java.util.Map-
Java Map集合 遍历 五种方式(包含 Lambda 表达式遍历)
https://www.cnblogs.com/miracle-luna/p/10995132.html
`
// 第五种遍历方式(JDK 1.8支持的 Lambda 表达式,强烈推荐!!!)
System.out.println(“\n第五种遍历方式:通过 Lambda 表达式,遍历 Key 和 Value”);
map.forEach((key, value) -> {
System.out.println(“Key: ” + key + “, Value: ” + value);
});
`
List集合 遍历 四种方式(包含 Lambda 表达式遍历)
https://www.cnblogs.com/miracle-luna/p/10995400.html
Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)
https://www.cnblogs.com/miracle-luna/p/10995539.html
Array数组 遍历 四种方式(包含 Lambda 表达式遍历)
https://www.cnblogs.com/miracle-luna/p/10995469.html
HashMap to return default value for non-found keys?
https://stackoverflow.com/questions/7519339/hashmap-to-return-default-value-for-non-found-keys
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#getOrDefault-java.lang.Object-V-
`
It does this by default. It returns null. 即,在找不到对应的key的时候,默认返回null。
// or Java 8 and later version
String result = myHashMap.getOrDefault(key, defaultValue);
`
https://stackoverflow.com/questions/934775/changing-value-after-its-placed-in-hashmap-changes-whats-inside-hashmap/30859349#30859349
https://blog.csdn.net/sinat_29384657/article/details/52933817
`
# map合并
Map 的 .putAll() 方法可以合并两个Map,只不过如果有相同的key那么用后面的覆盖前面的值
# map赋值
Java中用mapA对mapB进行赋值时,不要使用:
mapB = mapA; // 错误的方式
的方式;
而应该使用先clear然后putAll的方式:
mapB.clear();
mapB.putAll(mapA);
`
Java中(嵌套)map的pretty-print打印
Multi-line pretty-printing of (nested) collections in Java
https://stackoverflow.com/questions/15171699/multi-line-pretty-printing-of-nested-collections-in-java
https://stackoverflow.com/questions/10120273/pretty-print-a-map-in-java/30659764#30659764
`
import org.json.JSONObject;
System.out.println(new JSONObject(myMap).toString(2));
// 本地测试打印还行,但是如果希望赋值给某个变量就不太好用了
MapUtils.debugPrint(System.out, “myMap”, myMap);
`
https://mvnrepository.com/artifact/org.apache.commons/commons-collections4
Java中如何找出 hashmap 中 value 最大的那对 k-v 键值对?
https://stackoverflow.com/questions/5911174/finding-key-associated-with-max-value-in-a-java-map
https://stackoverflow.com/questions/49470423/get-the-highest-values-in-a-hashmap-in-java
https://stackoverflow.com/questions/7498751/get-the-keys-with-the-biggest-values-from-a-hashmap
`
import java.util.*;
public class HashmapTest {
public static void main(String[] args) {
Map map = new HashMap();
map.put(“name1”, 3);
map.put(“name2”, 14);
map.put(“name3”, 4);
map.put(“name4”, 14);
map.put(“name5”, 2);
map.put(“name6”, 6);
System.out.println(map);
int max = Collections.max(map.values());
List keys = new ArrayList();
for (Map.Entry entry : map.entrySet()) {
if (entry.getValue()==max) {
keys.add(entry.getKey());
}
}
System.out.println(keys);
}
}
`
在 Java 中初始化 List 的五种方法
https://blog.csdn.net/YZBYZZ/article/details/83722346
https://juejin.im/post/5bddcee3e51d4520b6639663
`
1. 构造 List 后使用 List.add 初始化
List stringList = new LinkedList();
stringList.add(“a”);
stringList.add(“b”);
stringList.add(“c”);
2. 使用 {{}} 双括号语法
List stringList = new LinkedList(){{
add(“a”);
add(“b”);
add(“c”);
}};
3. 使用 Arrays.asList #如果只是用来初始化常量,一些注意事项可以不用考虑
List stringList = Arrays.asList(“a”, “b”, “c”);
4. 使用 Stream (JDK8)
List list = Stream.of(“a”, “b”, “c”).collect(Collectors.toList());
5. 使用 Lists (JDK9)
List list = Lists.newArrayList(“a”, “b”, “c”);
这个和 Arrays.asList 一样简洁清晰。
`
Java中 HashMap 的初始化方法整理
`
# 简而言之,下面这两种是最通用也最好理解的方案,其它的要么是非常规方式 Collections 要么是有 Java 8/9 的要求,或者是需要额外的依赖(比如:Guava),一般情况下以下两种就能满足。
1. 在 static 语句块中初始化
public static Map articleMapOne = new HashMap();
static {
articleMapOne.put(“ar01”, “Intro to Map”);
articleMapOne.put(“ar02”, “Some article”);
}
2. 双括号语法
Map doubleBraceMap = new HashMap() {{
put(“key1”, “value1”);
put(“key2”, “value2”);
}};
`
How to directly initialize a HashMap (in a literal way)?
https://stackoverflow.com/questions/6802483/how-to-directly-initialize-a-hashmap-in-a-literal-way
Initialize a HashMap in Java
https://www.baeldung.com/java-initialize-hashmap
https://github.com/eugenp/tutorials/tree/master/java-collections-maps-2
Java 中 HashMap 初始化时赋值
https://www.cnblogs.com/pejsidney/p/9235343.html
面试官再问你 HashMap 底层原理,就把这篇文章甩给他看
https://mp.weixin.qq.com/s/fA4ohy2iRwWWRIRpkR0HLA
`
本篇文章主要包括以下内容:
· HashMap 的存储结构
· 常用变量说明,如加载因子等
· HashMap 的四个构造函数
· tableSizeFor()方法及作用
· put()方法详解
· hash()方法,以及避免哈希碰撞的原理
· resize()扩容机制及原理
· get()方法
· 为什么HashMap链表会形成死循环,JDK1.8做了哪些优化
# HashMap存储结构
这里需要区分一下,JDK1.7和 JDK1.8之后的 HashMap 存储结构。在JDK1.7及之前,是用【数组】加【链表】的方式存储的。
但是,众所周知,当链表的长度特别长的时候,查询效率将直线下降,查询的时间复杂度为 O(n)。因此,JDK1.8 把它设计为达到一个特定的阈值之后,就将【链表】转化为【红黑树】。
由于红黑树是一个自平衡的二叉搜索树,因此可以使查询的时间复杂度降为O(logn)。
`