所谓双列集合就是存在映射关系并且是成对存在的。
双列集合体系:
-------------| Map 如果是实现了Map接口的集合类,具备的特点: 存储的数据都是以键值对的形式存在的,键不可重复,值可以重复。
----------------| HashMap 底层也是基于哈希表实现 的。
----------------| TreeMap TreeMap也是基于红黑树(二叉树)数据结构实现 的, 特点:会对元素的键进行排序存储。
----------------| Hashtable 和hashMap实现原理一样,但是是线程安全的,执行效率低。出现于JDK1.0。
Map接口常用方法:
增加:
V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
删除:
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
void clear()
从此映射中移除所有映射关系(可选操作)。
查看:
int size()
返回此映射中的键-值映射关系数。
V
get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
。
判断:
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
boolen containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolen
containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
迭代
Set<K>
keySet()
返回此映射中包含的键的 Set
视图。
Collection<V> values()
返回此映射中包含的值的 Collection
视图。
Set<Map.Entry<K,V>>
entrySet()
返回此映射中包含的映射关系的 Set
视图。
Map.entr<K,V>中的方法
K getKey()
返回与此项对应的键。
V getValue()
返回与此项对应的值。
V setValue(V value)
用指定的值替换与此项对应的值(可选操作)。返回与此项对应的旧值
代码示例:
1 public class DemoMap { 2 public static void main(String[] args) { 3 Map<String,String> map = new HashMap<String, String>(); 4 //添加 5 map.put("a", "张三"); 6 map.put("b", "李四"); 7 map.put("c", "王五"); 8 System.out.println(map); 9 map.put("a", "赵六"); 10 System.out.println(map); 11 12 Map<String, String> map2 = new HashMap<String,String>(); 13 map2.put("d", "李磊"); 14 map2.put("e", "韩梅梅"); 15 map.putAll(map2); 16 System.out.println(map); 17 18 //查看 19 System.out.println("size:" + map.size()); 20 System.out.println("value:" + map.get("a")); 21 //迭代 22 Set<String> set = map.keySet(); 23 System.out.println("map中的key:"+set); 24 Collection<String> collection = map.values(); 25 System.out.println("map中的value:"+collection); 26 Set<Map.Entry<String, String>> entrySet = map.entrySet(); 27 Iterator<Map.Entry<String, String>> iterator = entrySet.iterator(); 28 while(iterator.hasNext()){ 29 Map.Entry<String, String> entry = iterator.next(); 30 // entry.setValue("哈哈哈"); 31 System.out.println("key:"+entry.getKey() + " value:"+entry.getValue()); 32 } 33 34 //判断 35 System.out.println("是否为空:"+map.isEmpty()); 36 System.out.println("key是否a:"+map.containsKey("a")); 37 System.out.println("value是否为空:"+map.containsValue("李磊")); 38 //删除 39 map.remove("e"); 40 System.out.println(map); 41 map.clear(); 42 System.out.println(map); 43 } 44 }
HashMap
HashMap的存储原理:
往HashMap添加元素的时候,首先会调用键的hashCode方法得到元素 的哈希码值,然后经过运算就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出的位置目前没有任何元素存储,那么该元素可以直接添加到哈希表中。
情况2:如果算出 的位置目前已经存在其他的元素,那么还会调用该元素的equals方法与这个位置上的元素进行比较,如果equals方法返回的是false,那么该元素允许被存储,如果equals方法返回的是true,那么该元素被视为重复元素,替换掉原来的旧值。
代码示例:
1 class Person{ 2 int id; 3 String name; 4 public Person(int id, String name) { 5 this.id = id; 6 this.name = name; 7 } 8 @Override 9 public int hashCode() { 10 return this.id; 11 } 12 @Override 13 public boolean equals(Object obj) { 14 Person person = (Person)obj; 15 return this.id == person.id; 16 } 17 @Override 18 public String toString() { 19 return "{id :"+ this.id + " 名字:"+ this.name+"}"; 20 } 21 } 22 23 public class DemoMap { 24 public static void main(String[] args) { 25 HashMap<Person, String> map = new HashMap<Person,String>(); 26 map.put(new Person(110, "张三"), "110"); 27 map.put(new Person(210, "李四"), "210"); 28 map.put(new Person(310, "王五"), "310"); 29 System.out.println(map); 30 map.put(new Person(310, "赵六"), "410"); 31 System.out.println(map); 32 } 33 }
TreeMap
TreeMap 要注意的事项:
1. 往TreeMap添加元素的时候,如果元素的键具备自然顺序,那么就会按照键的自然顺序特性进行排序存储。
2. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性, 那么键所属的类必须要实现Comparable接口,把键的比较规则定义在CompareTo方法上。
3. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,而且键所属的类也没有实现Comparable接口,那么就必须在创建TreeMap对象的时候传入比较器。
代码示例:
实现Comparable接口
1 class Person implements Comparable<Person>{ 2 int id; 3 String name; 4 public Person(int id, String name) { 5 this.id = id; 6 this.name = name; 7 } 8 @Override 9 public int hashCode() { 10 return this.id; 11 } 12 @Override 13 public boolean equals(Object obj) { 14 Person person = (Person)obj; 15 return this.id == person.id; 16 } 17 @Override 18 public String toString() { 19 return "{id :"+ this.id + " 名字:"+ this.name+"}"; 20 } 21 22 @Override 23 public int compareTo(Person o) { 24 return this.id-o.id; 25 } 26 } 27 28 public class DemoMap { 29 public static void main(String[] args) { 30 TreeMap<Person, String> treeMap = new TreeMap<Person, String>(); 31 treeMap.put(new Person(110, "张三"), "110"); 32 treeMap.put(new Person(310, "王五"), "310"); 33 treeMap.put(new Person(210, "李四"), "210"); 34 System.out.println(treeMap); 35 } 36 }
自定义比较器
1 import java.util.Comparator; 2 import java.util.TreeMap; 3 4 5 class Person{ 6 int id; 7 String name; 8 public Person(int id, String name) { 9 this.id = id; 10 this.name = name; 11 } 12 @Override 13 public int hashCode() { 14 return this.id; 15 } 16 @Override 17 public boolean equals(Object obj) { 18 Person person = (Person)obj; 19 return this.id == person.id; 20 } 21 @Override 22 public String toString() { 23 return "{id :"+ this.id + " 名字:"+ this.name+"}"; 24 } 25 26 } 27 28 class MapComparator implements Comparator<Person>{ 29 30 @Override 31 public int compare(Person o1, Person o2) { 32 return o1.id - o2.id; 33 } 34 } 35 36 public class DemoMap { 37 public static void main(String[] args) { 38 TreeMap<Person, String> treeMap = new TreeMap<Person, String>(new MapComparator()); 39 treeMap.put(new Person(110, "张三"), "110"); 40 treeMap.put(new Person(310, "王五"), "310"); 41 treeMap.put(new Person(210, "李四"), "210"); 42 System.out.println(treeMap); 43 } 44 }
HashTable
和hashMap实现原理一样,但是是线程安全的,执行效率低。出现于JDK1.0。