8.7.HashMap类和Hashtable类的用法TreeMap与ConcurrentHashMap
Map接口–集合接口–主要处理的是键值对结构的数据
键值对结构的数据—就是一个完成的数据是由键和键所对应的值组合而成的数据
例如:书的目录就是一种键值对结构
【标题----页码】
Map接口下的子类
HashMap类–public class HashMap【基于哈希表的实现的Map接口】
允许null的值和null键
数据保存是无序的
不能有重复的键,重复的键被算作是一个数据。
构造方法:
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与p指定的相同的映射 Map 。
例如
package wangxing20200822_1_1;
import java.util.HashMap;
public class Lian1 {
public static void main(String[] args) {
//HashMap()构造一个空的HashMap,默认初始容量(16)和默认负载系数(0.75).
HashMap map1=new HashMap();
//HashMap(int initialCapacity) 构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75
HashMap map2=new HashMap(20);
//HashMap(int initialCapacity, float loadFactor) 构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap map3=new HashMap(20,0.5f);
//HashMap(Map<? extends K,? extends V> m) 构造一个新的 HashMap与指定的相同的映射 Map 。
HashMap mp4=new HashMap(map3);
}
}
实例方法:
void clear() 清空集合。
Object put(Object key, Object value) 向集合中添加键值对数据
boolean containsKey(Object key) 判断集合中是否包含指定的键
boolean containsValue(Object value) 判断集合中是否包含指定的值
Object get(Object key) 根据指定的键得到该键对应的值
boolean isEmpty() 判断集合是否为空。
int size() 得到集合中键值对元素的个数
V remove(Object key) 根基指定的键删除对应的键值对数据值
Set keySet() 得到集合中所有的键保存到Set集合中
Collection values() 得到集合中所有的值保存到Collection集合中
Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
package wangxing20200822_1_1;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Lian2{
public static void main(String[] args) {
HashMap map1=new HashMap();
//Object put(Object key, Object value) 向集合中添加键值对数据
map1.put(55,"id");
map1.put(88,"zhangsan");
map1.put("height",1666);
map1.put(0,true);
//不能有重复的键,重复的键被算作是一个数据
//map1.put(55,true);
//能有重复的值
map1.put("wode",1666 );
//键和值都可以为null
map1.put(null,"test");
map1.put("java", null);
//int size() 得到集合中键值对元素的个数
System.out.println("size"+map1.size());
//boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println("containsKey=="+map1.containsKey("wode"));
//boolean containsValue(Object value) 判断集合中是否包含指定的值
System.out.println("containsKey=="+map1.containsValue("1666"));
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("get=="+map1.get("id"));
//V remove(Object key) 根基指定的键删除对应的键值对数据值
map1.remove(0);
System.out.println("size=="+map1.size());
System.out.println("get=="+map1.get(0));
//Set keySet() 得到集合中所有的键保存到Set集合中
Set k1=map1.keySet();
for(Object key:k1) {
System.out.println("key=="+key);
}
//可以使用迭代器来遍历保存有键的set集合
//Collection values() 得到集合中所有的值保存到Collection集合中
Collection col=map1.values();
//使用迭代器来遍历保存有值的Collection集合
Iterator t=col.iterator();
while(t.hasNext()) {
System.out.println("value=="+t.next());
}
//遍历HashMap集合
//Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Set<Map.Entry<Object,Object>> mapSet=map1.entrySet();
for(Map.Entry<Object,Object>entry:mapSet){
Object key=entry.getKey();
Object val=entry.getValue();
System.out.println(key+":"+val);
}
}
}
运行结果为
Hashtable类—public class Hashtable<K,V> 该类实现了一个哈希表,它将键映射到值。
无序
不能有null键/null值
用作键的对象必须实现hashCode方法和equals方法。
不能有重复的键,重复的键被算作是一个数据。
线程安全
构造方法
Hashtable() 构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。
Hashtable(int initialCapacity) 构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。
Hashtable(int initialCapacity, float loadFactor) 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。
Hashtable(Map<? extends K,? extends V> t) 构造一个与给定地图相同的映射的新哈希表。
例如
package wangxing20200822_2_1;
import java.util.HashMap;
import java.util.Hashtable;
public class Lian1 {
public static void main(String[] args) {
//Hashtable() 构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。
Hashtable table1=new Hashtable();
//Hashtable(int initialCapacity) 构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。
Hashtable table2=new Hashtable(20);
//Hashtable(int initialCapacity, float loadFactor) 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。
Hashtable table3=new Hashtable(30,0.5f);
//Hashtable(Map<? extends K,? extends V> t) 构造一个与给定地图相同的映射的新哈希表。
HashMap map1=new HashMap();
Hashtable table4=new Hashtable(map1);
}
}
实例方法
void clear() 清空集合。
Object put(Object key, Object value) 向集合中添加键值对数据
boolean containsKey(Object key) 判断集合中是否包含指定的键
boolean containsValue(Object value) 判断集合中是否包含指定的值
Object get(Object key) 根据指定的键得到该键对应的值
boolean isEmpty() 判断集合是否为空。
int size() 得到集合中键值对元素的个数
V remove(Object key) 根基指定的键删除对应的键值对数据值
Set keySet() 得到集合中所有的键保存到Set集合中
Collection values() 得到集合中所有的值保存到Collection集合中
Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Enumeration keys() 返回此散列表中键的枚举。
Enumeration elements() 返回此散列表中值的枚举。
例如:
package wangxing20200822_2_1;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Lian2 {
public static void main(String[] args) {
Hashtable table1=new Hashtable();
table1.put("ad",558);
table1.put(6666,"zhangsan");
//不能有重复的键,重复的键算一个,值可以重复
table1.put(0,true);
table1.put(1, true);
//不能null
//table1.put(null,ture);
//table.put(true,null);
System.out.println("size=="+table1.size());
//boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println("containsKey=="+table1.containsKey("ad"));
//boolean containsValue(Object value) 判断集合中是否包含指定的值
System.out.println("containsKey=="+table1.containsValue("zhangsan"));
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("get=="+table1.get("0"));
//V remove(Object key) 根据指定的键删除对应的键值对数据值
table1.remove(0);
System.out.println("size=="+table1.size());
System.out.println("size=="+table1.get(0));
//Set keySet() 得到集合中所有的键保存到Set集合中
Set keyset=table1.keySet();
for(Object key:keyset) {
System.out.println("key=="+key);
}
//可以使用迭代器来遍历保存有键的set集合
//Collection values() 得到集合中所有的值保存到Collection集合中
Collection i=table1.values();
//使用迭代器来遍历保存有值的Collection集合
Iterator it=i.iterator();
while(it.hasNext()) {
System.out.println("value=="+it.next());
//遍历HashMap集合
//Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Set<Map.Entry<Object,Object>> mapSet=table1.entrySet();
for(Map.Entry<Object,Object>entry:mapSet){
Object key=entry.getKey();
Object val=entry.getValue();
}
}
}
}
运行结果:
TreeMap类–红黑树基于NavigableMap实现【有序】
ConcurrentHashMap类—线程安全,支持高并发,哈希表
8.8.HashMap类与Hashtable类与TreeMap类与ConcurrentHashMap类的区别
HashMap底层实现原理
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。
HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。
ConcurrentHashMap使用了分割,将一个map分成多个小的hashtable,对map的一部分进行上锁。保证同步的同时,有提高了性能。
8.9.认识Collections类【集合类的帮助类】
public class Collections----此类仅由静态方法组合或返回集合
此类中的方法都是静态方法,静态方法为了帮助我们更加方便的操作集合中的数据。
static <T extends Comparable<? super T>>
void sort(List list) 根据其元素的natural ordering对指定的列表进行排序。
static void reverse(List<?> list) 反转指定列表中元素的顺序。
static void copy(List<? super T> dest, List<? extends T> src) 将所有元素从一个列表复制到另一个列表中。
static <T extends Object & Comparable<? super T>>
T max(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最大元素。
static <T extends Object & Comparable<? super T>>
T min(Collection<? extends T> coll)
根据其元素的 自然顺序返回给定集合的最小元素。
例如:
package wangxing20200822_3_1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class Lian {
public static void main(String[] args) {
//sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。
ArrayList arr1=new ArrayList();
arr1.add("xiaoming");
arr1.add("wode");
arr1.add("nide");
arr1.add("xiao");
Collections.sort(arr1);
for(Object x:arr1) {
System.out.println(x);
}
System.out.println("________");
//reverse(List<?>list)反转指定列表中元素的顺序
Collections.reverse(arr1);
for(Object x1:arr1) {
System.out.println(x1);
}
ArrayList arr2=new ArrayList();
arr2.add(123);
arr2.add(456);
arr2.add(4567);
arr2.add(2);
System.out.println(Collections.max(arr2));
System.out.println(Collections.min(arr2));
Collections.copy(arr2, arr1);
for(Object s:arr2) {
System.out.println(s);
}
}
}
运行结果:
注意与Arrays的比较
8.10.Collection接口与Collections类的区别