• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

java8 hashMap排序的新认识

随记 来源:崂启逗逗 3次浏览
public static void main(String[] args) {
		// 创建map
		Map<String, Integer> maps = new HashMap<String, Integer>();
		maps.put("12", 12);
		maps.put("11", 11);
		maps.put("2", 2);
		// 输出 初始化后的map
		maps.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());
		// 排序完后返回list
		listMap.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);
		});

		// 排序完后返回Iterator
		Iterator<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 毫无意义,因为他们的存放机制是这样的.


版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)