Writer:BYSocket(泥沙砖瓦浆木匠)java
微博:BYSocketweb
豆瓣:BYSocket算法
Java 容器的文章此次应该是最后一篇了:Java 容器 系列。 今天泥瓦匠聊下 Maps。安全
Map,又称映射表,是将键映射到值的对象。有四种实现Map接口而且常用的Map集合为:HashMap,TreeMap,Hashtable 和 LinkedHashMap.并发
泥瓦匠记忆宫殿:框架
一、一个映射不包含重复的键。socket
二、每一个键最多只能映射到一个值。函数
HashMap是基于哈希表的Map接口的实现。其对键进行散列,散列函数只能做用于键。下面模拟下,公司员工和找员工的例子:oop
import java.util.HashMap; import java.util.Map; class Employee {} public class HaspMap01 { public static void main(String[] args) { Map<String, Employee> employees = new HashMap<String, Employee>(); employees.put("1206010035", new Employee()); System.out.println(employees); String number = "1206010035"; System.out.println(employees.get(number)); } }
?Run一下,你们能够见到结果:put方法,能够将键值映射添加进表。get方法则返回指定键所映射的值。从他们 hashCode 能够看出是同一个对象。性能
HaspMap的键必须惟一,一样其同一个键不能存放两个值,若是对同一个键两次调用put方法,第二个值会取代第一个值。一样是容许使用 null 值和 null 键。下面泥瓦匠用一个简单的例子解释下:
package javaBasic.collection.map; import java.util.HashMap; import java.util.Map; public class HaspMap02 { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Map map = new HashMap<String, String>(); map.put(null, "null01"); map.put(null, "null02"); System.out.println(map); System.out.println(map.get(null)); } }
结果以下:
{null=null02} null02
因而可知,第一个值被第二个值所替换了。
下面有三点是HashMap重要之处:
一、HashMap的构造函数
HaspMap构造函数涉及两个参数:初始容量和加载因子。初试容量是哈希表建立时的其中桶的含量。加载因子是哈希表在其容量自动增长以前能够达到多满的一种尺度。这两个参数都是影响HashMap的性能。默认构造一个具备默认初始容量 (16) 和默认加载因子 (0.75)。默认加载因子 (.75) 在时间和空间成本上是一种折衷的考虑。
二、和上次总结的Set都差很少,这个HashMap线程是不安全不一样步的。若是想防止意外发生,则设置成同步便可:
Map m = Collections.synchronizedMap(new HashMap(...));
三、不一样步的话,意味着存在快速失败致使的并发修改异常。
下面看一个复杂例子:
package javaBasic.collection.map; import java.util.HashMap; import java.util.Map.Entry; class A { public boolean equals(Object obj) { return true; } } class B { public int hashCode() { return 1; } } class C { public int hashCode() { return 2; } public boolean equals(Object obj) { return true; } } public class HashMap03 { public static void main(String[] args) { HashMap<A, Integer> hashMapA = new HashMap<A, Integer>(); hashMapA.put(new A(), 10); hashMapA.put(new A(), 5); System.out.println("HashMapA Elements:"); System.out.print("\t" + hashMapA + "\n"); // loop HashMapA for(Entry<A, Integer> entryA : hashMapA.entrySet()) { System.out.println(entryA.getKey().toString()+"-"+entryA.getValue()); } HashMap<B, Integer> hashMapB = new HashMap<B, Integer>(); hashMapB.put(new B(), 10); hashMapB.put(new B(), 5); System.out.println("HashMapB Elements:"); System.out.print("\t" + hashMapB + "\n"); // loop HashMapB for(Entry<B, Integer> entryB : hashMapB.entrySet()) { System.out.println(entryB.getKey().toString()+"-"+entryB.getValue()); } HashMap<C, Integer> hashMapC = new HashMap<C, Integer>(); hashMapC.put(new C(), 10); hashMapC.put(new C(), 5); System.out.println("HashMapC Elements:"); System.out.print("\t" + hashMapC + "\n"); // loop HashMap for(Entry<C, Integer> entryC : hashMapC.entrySet()) { System.out.println(entryC.getKey().toString()+"-"+entryC.getValue()); } } }
运行一下,能够看到如下结果:
因而可知,其中和 Java 容器 & 泛型:3、HashSet,TreeSet 和 LinkedHashSet比较 中涉及的知识点一致:
集合判断两个元素相等不仅仅是equals方法,而且必须hashCode()方法返回值也要相等。
TreeMap使v用树结构实现(红黑树),集合中的元素进行排序,可是添加、删除和包含的算法复杂度为O(log(n))。其实Map特性基本都是一致的,好比看下面的简单例子:
public class TreeMap01 { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { Map map = new TreeMap(); map.put("1", "1"); map.put("4", "4"); map.put("2", "2"); map.put("2", "3"); System.out.println(map); } }
结果以下:
{1=1, 2=3, 4=4}
从中咱们能够看出
一、TreeMap实现了SortedMap,顾名思义,其表示为有排序的集合。
二、一样其同一个键不能存放两个值,若是对同一个键两次调用put方法,第二个值会取代第一个值。
HashMap与TreeMap
一、HashMap经过hashcode对其内容进行快速查找,而TreeMap中全部的元素都保持着某种固定的顺序,若是你须要获得一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。HashMap中元素的排列顺序是不固定的)。
二、 HashMap经过hashcode对其内容进行快速查找,而TreeMap中全部的元素都保持着某种固定的顺序,若是你须要获得一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。
三、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但若是您要按天然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明肯定义了hashCode()和 equals()的实现。 这个TreeMap没有调优选项,由于该树总处于平衡状态。
Writer:BYSocket(泥沙砖瓦浆木匠)
微博:BYSocket
豆瓣:BYSocket