java8 hashMap排序的新认识

来源:互联网 发布:南京专业除甲醛 知乎 编辑:程序博客网 时间:2024/06/14 00:15
public static void main(String[] args) {// 创建mapMap<String, Integer> maps = new HashMap<String, Integer>();maps.put("12", 12);maps.put("11", 11);maps.put("2", 2);// 输出 初始化后的mapmaps.forEach((k, v) -> {System.out.println("原始map:" + k + "->" + v);});maps = maps.entrySet().stream().sorted(Map.Entry.<String, Integer> comparingByValue().reversed()).collect(Collectors.toMap(c -> c.getKey(), c -> c.getValue()));List<Entry<String, Integer>> listMap = maps.entrySet().stream().sorted(Map.Entry.<String, Integer> comparingByValue().reversed()).collect(Collectors.toList());// 排序完后返回listlistMap.forEach(e -> {System.out.println("排序完后返回List<Entry<String, Integer>>:"+ e.getKey() + "->" + e.getValue());});// key值排序List<String> list = maps.keySet().stream().sorted((c1, c2) -> c2.compareTo(c1)).collect(Collectors.toList());maps.forEach((k, v) -> {System.out.println("排序完后返回map:" + k + "->" + v);});list.forEach(e -> {System.out.println("key值单独排序返回list<String>:" + e);});// 排序完后返回IteratorIterator<Map.Entry<String, Integer>> entryIterator = maps.entrySet().stream().filter(e -> StringUtils.isNotBlank(e.getKey())).sorted(Map.Entry.<String, Integer> comparingByValue().reversed()).iterator();// 排序while (entryIterator.hasNext()) {Map.Entry<String, Integer> o = entryIterator.next();System.out.println("排序完后返回迭代器:" + o.getKey() + "->" + o.getValue());}}

输出结果:

原始map:11->11
原始map:12->12
原始map:2->2
排序完后返回List<Entry<String, Integer>>:12->12
排序完后返回List<Entry<String, Integer>>:11->11
排序完后返回List<Entry<String, Integer>>:2->2
排序完后返回map:11->11
排序完后返回map:12->12
排序完后返回map:2->2
key值单独排序返回list<String>:2
key值单独排序返回list<String>:12
key值单独排序返回list<String>:11
排序完后返回迭代器:12->12
排序完后返回迭代器:11->11
排序完后返回迭代器:2->2   






抄录一下:

HashSet 和 HashMap 之间有很多相似之处,对于 HashSet 而言,系统采用 Hash 算法决定集合元素的存储位置,这样可以保证能快速存、取集合元素;对于 HashMap 而言,系统 key-value 当成一个整体进行处理,系统总是根据 Hash 算法来计算 key-value 的存储位置,这样可以保证能快速存、取 Map 的 key-value 对。 

当程序执行 map.put("12" , 12); 时,系统将调用"12"的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。得到这个对象的 hashCode 值之后,系统会根据该 hashCode 值来决定该元素的存储位置。 

 public V put(K key, V value)  {  // 如果 key 为 null,调用 putForNullKey 方法进行处理 if (key == null)  return putForNullKey(value);  // 根据 key 的 keyCode 计算 Hash 值 int hash = hash(key.hashCode());  // 搜索指定 hash 值在对应 table 中的索引  int i = indexFor(hash, table.length); // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素 for (Entry<K,V> e = table[i]; e != null; e = e.next)  {  Object k;  // 找到指定 key 与需要放入的 key 相等(hash 值相同 // 通过 equals 比较放回 true) if (e.hash == hash && ((k = e.key) == key  || key.equals(k)))  {  V oldValue = e.value;  e.value = value;  e.recordAccess(this);  return oldValue;  }  }  // 如果 i 索引处的 Entry 为 null,表明此处还没有 Entry  modCount++;  // 将 key、value 添加到 i 索引处 addEntry(hash, key, value, i);  return null;  } 


根据上面 put 方法的源代码可以看出,当程序试图将一个 key-value 对放入 HashMap 中时,程序首先根据该 key 的 hashCode() 返回值决定该 Entry 的存储位置:如果两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置相同。如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但 key 不会覆盖。如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部——具体说明继续看 addEntry() 方法的说明。


所以对hashmap 排序如果还是返回hashMap 毫无意义,因为他们的存放机制是这样的.

2 0
原创粉丝点击