1.Map API
(1)Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
java.util Interface Map<K,V> 参数类型:K--Map的Key(键) V--Map的与Key对应的Value(值) 实现的子类:AbstractMap , Attributes , EnumMap , HashMap, Hashtable , LinkedHashMap , |
(2)Map.Entry,是Map的嵌套类,它用来描述Map中的键/值对。
static interface Map.Entry<K,V> :Map条目(键值对)。
(3)覆盖Object 的两个方法,以正确比较 Map 对象的等价性
(4)常用方法
void clear() 从该地图中删除所有的映射(可选操作)。 |
boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true。 |
boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。 |
int size() 返回此地图中键值映射的数量。 |
Collection<V> values() 返回此地图中包含的值的Collection视图。 |
default void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。 |
2.HashMap
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
直接子类:LinkedHashMap , PrinterStateReasons
HashMap基于哈希表(“拉链法”实现哈希表,可参见数据结构-哈希表)实现的Map接口,。 此实现提供了所有可选的Map操作,并允许null的值和null键。
HashMap类大致相当于Hashtable ,除了它是不同步的,如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,那么它必须在外部进行同步。。
这个类不能保证Map的顺序; 特别是,它不能保证订单在一段时间内保持不变。
构造方法 |
HashMap() :构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。(见下面注意) |
HashMap(int initialCapacity) :构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。 |
HashMap(int initialCapacity, float loadFactor) :构造一个空的 HashMap具有指定的初始容量和负载因子。 |
HashMap(Map<? extends K,? extends V> m): 构造一个新的 HashMap与指定的相同的映射 Map 。 |
注意:
HashMap的一个实例有两个影响其性能的参数: 初始容量和负载因子 。 容量是哈希表中的桶数,初始容量只是创建哈希表 (数据结构-哈希表)时的容量。 负载因子是在容量自动增加之前允许哈希表得到满足的度量。 当在散列表中的条目的数量超过了负载因数和容量的乘积,哈希表被重新散列 (即,内部数据结构被重建),使得哈希表具有桶的大约两倍。
作为一般规则,默认负载因子(.75)提供了时间和空间成本之间的良好折中。 更高的值会降低空间开销,但会增加查找成本(反映在 HashMap类的大部分操作中,包括get和put )。 在设置其初始容量时,应考虑Map中预期的条目数及其负载因子,以便最小化重新组播操作的数量。 如果初始容量大于最大条目数除以负载因子,则不会发生重新排列操作。
常用方法和Map相同
3.Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map <K,V>, Cloneable ,Serializable
已知直接子类: Properties , UIDefaults
该类实现了一个哈希表(“拉链法”实现哈希表),它将键映射到值。 任何非null
对象都可以用作键值或值。
为了从散列表成功存储和检索对象,用作键的对象必须实现hashCode
方法和equals
方法。
构造方法 |
Hashtable() :构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。 |
Hashtable(int initialCapacity) :构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。 |
Hashtable(int initialCapacity, float loadFactor): 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。 |
Hashtable(Map<? extends K,? extends V> t) :构造一个与给定地图相同的映射的新哈希表。 |
Hashtable 与HashMap比较
相同点:
- 都实现了Map、Cloneable、Serializable接口
- 底层都是基于“拉链法”实现哈希表
不同的:
- 线程安全不同:HashMap单线程安全,HashTable多线程安全
- NULL的处理不同:HashMap的Key和Value可以为Null,HashTable的Key和Value非 Null
- 遍历:HashMap支持Iterator;HashTable支持Iterator和Enumeration
- 类型不同:HashMap基于AbstractMap,HashTable基于Dictionary
4.TreeMap
public class TreeMap<K,V>
extends AbstractMap <K,V>
implements NavigableMap<K,V>, Cloneable , Serializable
TreeMap基于红黑树实现
NavigableMap。红黑树是一种自平衡的二叉树,即左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。红黑树虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。(点击查看关于数据结构---红黑树的文章) |
构造方法 |
TreeMap():使用其键的自然排序构造一个新的空树状图。 |
TreeMap(Comparator<? super K> comparator):构造一个新的,空的树图,按照给定的比较器排序。 |
TreeMap(Map<? extends K,? extends V> m) :造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序 。 |
TreeMap(SortedMap<K,? extends V> m) :造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。 |
5.Properties
public class Properties
extends Hashtable <Object ,Object>
直接子类:ProviderProperties类表示一组持久的属性。看参见Java I/O---Properties类(持久化键值对)因为Properties从继承Hashtable时, put种putAll方法可应用于Properties对象。 强烈不鼓励使用它们,因为它们允许调用者插入其键或值不是Strings , 应该使用setProperty方法。这个类是线程安全的:多个线程可以共享一个Properties对象,而不需要外部同步。
构造方法 |
Properties() :创建一个没有默认值的空属性列表。 |
Properties(Properties defaults):创建具有指定默认值的空属性列表。 |
常用方法 |
String getProperty(String key) :使用此属性列表中指定的键搜索属性。 |
String getProperty(String key, String defaultValue) :使用此属性列表中指定的键搜索属性。 |
void list(PrintStream out /PrintWriter out) : 将此属性列表打印到指定的输出流 |
void load(InputStream inStream/Reader reader) : 从输入字节流读取属性列表(键和元素对)。 |
void loadFromXML(InputStream in) :将指定输入流中的XML文档表示的所有属性加载到此属性表中。 |
Enumeration<?> propertyNames() :返回此属性列表中所有键的枚举,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
Object setProperty(String key, String value) :取代 Hashtable方法 put 。 |
void storeToXML(OutputStream os, String comment, String encoding) :使用指定的编码发出表示此表中包含的所有属性的XML文档。 |
Set<String> stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
6.Map的方法演示
1 public class MapDemo { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 Map<Integer,String> map = new HashMap<Integer,String>(); 9 methodDemo(map); 10 /* 11 * 需求:Map集合中存储学号,姓名。 12 */ 13 } 14 public static void methodDemo(Map<Integer,String> map){ 15 16 //1,存储键值对。如果键相同,会出现值覆盖。 17 System.out.println(map.put(3, "xiaoqiang")); 18 System.out.println(map.put(3, "erhu")); 19 map.put(7, "wangcai"); 20 map.put(2, "daniu"); 21 22 // System.out.println(map.remove(7)); 23 24 System.out.println(map.get(7)); 25 26 System.out.println(map); 27 } 28 }
1 public class MapTest { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 /* 9 * 什么时候使用map集合呢? 10 * 当需求中出现映射关系时,应该最先想到map集合。 11 * 12 */ 13 14 String cnWeek = getCnWeek(3); 15 System.out.println(cnWeek); 16 String enWeek = getEnWeek("星期八"); 17 System.out.println(enWeek); 18 19 } 20 //根据中文星期,获取对应的英文星期。 21 //中文与英文相对应,可以建立表,没有有序的编号,只能通过map集合。 22 public static String getEnWeek(String cnWeek){ 23 24 //创建一个表。 25 Map<String,String> map = new HashMap<String,String>(); 26 map.put("星期一","Monday"); 27 map.put("星期二","Tuesday"); 28 map.put("星期三","Wednesday"); 29 map.put("星期四","Thursday"); 30 map.put("星期五","Friday"); 31 map.put("星期六","Saturday"); 32 map.put("星期日","Sunday"); 33 34 35 return map.get(cnWeek); 36 37 } 38 39 /** 40 * 根据用户的指定的数据获取对应的星期。 41 */ 42 public static String getCnWeek(int num){ 43 44 if(num<=0 || num>7){ 45 throw new NoWeekException(num+",没有对应的星期"); 46 } 47 48 String[] cnWeeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"}; 49 50 return cnWeeks[num]; 51 52 } 53 54 } 55
1 public class Employee implements Comparable<Employee> { 2 3 private String name; 4 private int age; 5 6 7 public Employee() { 8 super(); 9 10 } 11 12 public Employee(String name, int age) { 13 super(); 14 this.name = name; 15 this.age = age; 16 } 17 18 public String getName() { 19 return name; 20 } 21 public void setName(String name) { 22 this.name = name; 23 } 24 public int getAge() { 25 return age; 26 } 27 public void setAge(int age) { 28 this.age = age; 29 } 30 31 @Override 32 public String toString() { 33 return "Emplooye [name=" + name + ", age=" + age + "]"; 34 } 35 36 @Override 37 public int hashCode() { 38 final int prime = 31; 39 int result = 1; 40 result = prime * result + age; 41 result = prime * result + ((name == null) ? 0 : name.hashCode()); 42 return result; 43 } 44 45 @Override 46 public boolean equals(Object obj) { 47 if (this == obj) 48 return true; 49 if (obj == null) 50 return false; 51 if (getClass() != obj.getClass()) 52 return false; 53 Employee other = (Employee) obj; 54 if (age != other.age) 55 return false; 56 if (name == null) { 57 if (other.name != null) 58 return false; 59 } else if (!name.equals(other.name)) 60 return false; 61 return true; 62 } 63 64 @Override 65 public int compareTo(Employee o) { 66 67 int temp = this.age - o.age; 68 return temp==0? this.name.compareTo(o.name):temp; 69 } 70 71 } 72 73 /////////////////////////////////////////////////////////////////////////////////////////// 74 public class HashMapTest { 75 76 /** 77 * @param args 78 */ 79 public static void main(String[] args) { 80 /* 81 * 1, 将员工和归属存储到HashMap集合中并取出。 同姓名同年龄视为同一个学生。 82 */ 83 84 85 Map<Employee,String> map = new HashMap<Employee,String>();//如果改成LinkedHashMap可以实现有序。 86 87 map.put(new Employee("xiaozhang",24),"北京"); 88 map.put(new Employee("laoli",34),"上海"); 89 map.put(new Employee("mingming",26),"南京"); 90 map.put(new Employee("xili",30),"广州"); 91 map.put(new Employee("laoli",34),"铁岭"); 92 93 Set<Employee> keySet = map.keySet(); 94 for(Employee employee : keySet){ 95 96 String value = map.get(employee); 97 98 System.out.println(employee.getName()+":"+employee.getAge()+"...."+value); 99 100 101 } 102 103 // for(Employee employee : map.keySet()){ 104 // 105 // } 106 107 108 } 109 110 111 112 } 113
1 public class TreeMapTest { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 /* 9 * 2, 按照学生的年龄进行升序排序并取出。 按照学生的姓名进行升序排序并取出。 10 */ 11 12 // 自定义比较器。 13 Comparator<Employee> comparator = new Comparator<Employee>() { 14 15 @Override 16 public int compare(Employee o1, Employee o2) { 17 18 int temp = o1.getName().compareTo(o2.getName()); 19 return temp == 0 ? o1.getAge() - o2.getAge() : temp; 20 } 21 }; 22 23 Map<Employee, String> map = new TreeMap<Employee, String>(comparator); 24 25 map.put(new Employee("xiaozhang", 24), "北京"); 26 map.put(new Employee("laoli", 34), "上海"); 27 map.put(new Employee("mingming", 26), "南京"); 28 map.put(new Employee("xili", 30), "广州"); 29 map.put(new Employee("laoli", 34), "铁岭"); 30 31 // entrySet 32 Set<Map.Entry<Employee, String>> entrySet = map.entrySet(); 33 for (Map.Entry<Employee, String> me : entrySet) { 34 35 Employee key = me.getKey(); 36 String value = me.getValue(); 37 System.out.println(key.getName() + "::" + key.getAge() + "....." 38 + value); 39 } 40 41 } 42 43 } 44
2018-01-07
内容主要来自API