集合框架-2
1.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与指定的相同的映射 Map 。 |
package com.wangxing.hashmaptest;
import java.util.HashMap;
public class HashMapTest1 {
public static void main(String[] args) {
//Map接口下的子类
//HashMap类
//允许null的值和null键
//数据保存是无序的
//不能有重复的键,重复的键被算作是一个数据。
//构造方法:
//HashMap() 构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。
HashMap map1=new HashMap();
//HashMap(int initialCapacity) 构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。
HashMap map2=new HashMap(30);
//HashMap(int initialCapacity, float loadFactor) 构造一个空的 HashMap具有指定的初始容量和负载因子。
HashMap map3=new HashMap(30,0.5f);
//HashMap(Map m) 构造一个新的 HashMap与指定的相同的映射 Map 。
HashMap map4=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 com.wangxing.hashmaptest;
import java.util.HashMap;
public class HashMapTest2 {
public static void main(String[] args) {
//HashMap类常用实例方法
//允许null的值和null键
//数据保存是无序的
//不能有重复的键,重复的键被算作是一个数据。
HashMap map1=new HashMap();
//Object put(Object key, Object value) 向集合中添加键值对数据
map1.put("hello",1234);
map1.put(1234,"hello");
map1.put(12.5,true);
map1.put(false,168.5);
map1.put(null,"null键");
map1.put("null值",null);
//map1.put(null,null);
//int size() 得到集合中键值对元素的个数
System.out.println("size=="+map1.size());
//boolean containsKey(Object key) 判断集合中是否包含指定的键
String containsKey=(map1.containsKey("helloworld"))?"存在":"不存在";
System.out.println("containsKey=="+containsKey);
//boolean containsValue(Object value) 判断集合中是否包含指定的值
String containsValue=(map1.containsValue("helloworld"))?"存在":"不存在";
System.out.println("containsValue=="+containsValue);
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("get=="+map1.get(1234)); //hello
//V remove(Object key) 根基指定的键删除对应的键值对数据值
map1.remove("null值");
System.out.println("size=="+map1.size());
//void clear() 清空集合。
//boolean isEmpty() 判断集合是否为空。
/*
Set keySet() 得到集合中所有的键保存到Set集合中
Collection values() 得到集合中所有的值保存到Collection集合中
Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据保存到Set集合中
*/
}
}
便利HashMap
package com.wangxing.hashmaptest;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapTest3 {
public static void main(String[] args) {
//HashMap类的遍历
HashMap<Object,Object> map1=new HashMap<Object,Object>();
map1.put("hello",1234);
map1.put(1234,"hello");
map1.put(12.5,true);
map1.put(false,168.5);
map1.put(null,"null键");
map1.put("null值",null);
//遍历集合中所有的键保存到Set集合中Set keySet()
Set setkey=map1.keySet();
for(Object key:setkey){
System.out.println("key=="+key);
}
System.out.println("--------");
Iterator iterator=setkey.iterator();
while(iterator.hasNext()){
Object key=iterator.next();
System.out.println("key=="+key);
}
System.out.println("--------");
//遍历集合中所有的值保存到Collection集合中 values()
Collection valuecoll=map1.values();
for(Object val:valuecoll){
System.out.println("val=="+val);
}
System.out.println("--------");
Iterator iteratorval=valuecoll.iterator();
while(iteratorval.hasNext()){
Object val=iteratorval.next();
System.out.println("val=="+val);
}
System.out.println("--------");
//Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据保存在Set集合中
Set keyvalset=map1.entrySet();
for(Object obj:keyvalset){
System.out.println(obj);
}
System.out.println("--------");
for(Map.Entry<Object,Object> entry:map1.entrySet()){
System.out.println(entry.getKey()+"----"+entry.getValue());
}
}
}
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 com.wangxing.hashtabletest;
import java.util.HashMap;
import java.util.Hashtable;
public class HashtableTest1 {
public static void main(String[] args) {
//Hashtable类
//无序
//不能有null键/null值
//用作键的对象必须实现hashCode方法和equals方法。
//不能有重复的键,重复的键被算作是一个数据。
//线程安全
//构造方法
//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(20,0.5f);
//Hashtable(Map t) 构造一个与给定地图相同的映射的新哈希表。
Hashtable table4=new Hashtable(table3);
HashMap map1=new HashMap();
Hashtable table5=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<K> |
keys() 返回此散列表中键的枚举。 |
|
Enumeration<V> |
elements() 返回此散列表中值的枚举。 |
package com.wangxing.hashtabletest;
import java.util.HashMap;
import java.util.Hashtable;
public class HashtableTest2 {
public static void main(String[] args) {
//Hashtable类常用实例方法
//无序
//不能有null键/null值
//用作键的对象必须实现hashCode方法和equals方法。
//不能有重复的键,重复的键被算作是一个数据。
//线程安全
Hashtable table1=new Hashtable();
//Object put(Object key, Object value) 向集合中添加键值对数据
table1.put("hello",1234);
table1.put(1234,"hello");
table1.put(12.5,true);
table1.put(false,168.5);
//不能有null键/null值
//table1.put(null,"null键");
//table1.put("null值",null);
//用作键的对象必须实现hashCode方法和equals方法。
UserBean user=new UserBean();
table1.put(user,"userbean");
//int size() 得到集合中键值对元素的个数
System.out.println("size=="+table1.size());
//boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println("containsKey=="+table1.containsKey("user"));
//boolean containsValue(Object value) 判断集合中是否包含指定的值
System.out.println("containsValue=="+table1.containsValue("user"));
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("get=="+table1.get(user)); //userbean
//V remove(Object key) 根据指定的键删除对应的键值对数据值
table1.remove(user);
System.out.println("size=="+table1.size());
//void clear() 清空集合。
//boolean isEmpty() 判断集合是否为空。
/*
Set keySet() 得到集合中所有的键保存到Set集合中
Collection values() 得到集合中所有的值保存到Collection集合中
Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Enumeration<K> keys() 返回此散列表中键的枚举。
Enumeration<V> elements() 返回此散列表中值的枚举。
*/
}
class UserBean{
}
}
便利Hashtable
package com.wangxing.hashtabletest;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashtableTest3 {
public static void main(String[] args) {
//Hashtable类的遍历
Hashtable<Object,Object> table1=new Hashtable<Object,Object>();
table1.put("hello",1234);
table1.put(1234,"hello");
table1.put(12.5,true);
table1.put(false,168.5);
//遍历所有键Set keySet()/Enumeration<K> keys()
Set keys=table1.keySet();
for(Object key:keys){
System.out.println("key=="+key);
}
System.out.println("-------");
Iterator iteratorkey=keys.iterator();
while(iteratorkey.hasNext()){
Object key=iteratorkey.next();
System.out.println("key=="+key);
}
System.out.println("-------");
Enumeration<Object> enukey=table1.keys();
while(enukey.hasMoreElements()){
Object key=enukey.nextElement();
System.out.println("key=="+key);
}
System.out.println("-------");
//遍历所有值Collection values() /Enumeration<V> elements()
Collection valuecoll=table1.values();
for(Object val:valuecoll){
System.out.println("val=="+val);
}
System.out.println("-------");
Iterator iteratorval=valuecoll.iterator();
while(iteratorval.hasNext()){
Object val=iteratorval.next();
System.out.println("val=="+val);
}
System.out.println("-------");
Enumeration<Object> values=table1.elements();
while(values.hasMoreElements()){
Object val=values.nextElement();
System.out.println("val=="+val);
}
System.out.println("-------");
//Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Set keyvalueset= table1.entrySet();
for(Object keyvalue:keyvalueset){
System.out.println(keyvalue);
}
System.out.println("-------");
for(Map.Entry<Object, Object> entry:table1.entrySet()){
System.out.println(entry.getKey()+"--"+entry.getValue());
}
}
}
TreeMap类--红黑树基于NavigableMap实现【有序】
ConcurrentHashMap类---线程安全,支持高并发,哈希表
2.HashMap类与Hashtable类与TreeMap类与ConcurrentHashMap类的区别
HashMap类 |
Hashtable类 |
可以有null键/null值 |
不能有null键/null值 |
HashMap继承AbstractMap类 |
Hashtable继承Dictionary类 |
默认容量为16 |
默认容量为11 |
将容量变为原来的2倍。 |
将容量变为原来的2倍加1 |
线程不安全 |
线程安全 |
HashMap底层实现原理
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。
HashMap类 |
ConcurrentHashMap类 |
线程不安全 |
线程安全 |
Hashtable类 |
ConcurrentHashMap类 |
线程安全高并发时效率低 |
线程安全高并发时效率高 |
HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。
ConcurrentHashMap使用了分割,将一个map分成多个小的hashtable,对map的一部分进行上锁。保证同步的同时,有提高了性能。
HashMap类 |
Hashtable类 |
TreeMap类 |
无序 哈希表 |
无序 哈希表 |
有序的key-value集合 红黑树实现 |
HashMap继承AbstractMap类 |
Hashtable继承Dictionary类 |
继承AbstractMap类 NavigableMap接口 |
线程不安全 |
线程安全 |
线程不安全 |
3.认识Collections类【集合类的帮助类】
public class Collections----此类仅由静态方法组合或返回集合
此类中的方法都是静态方法,静态方法为了帮助我们更加方便的操作集合中的数据。
static <T extends Comparable<? super T>> |
sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。 |
|
static void |
reverse(List<?> list) 反转指定列表中元素的顺序。 |
|
static <T> void |
copy(List<? super T> dest, List<? extends T> src) 将所有元素从一个列表复制到另一个列表中。 |
|
static <T extends Object & Comparable<? super T>> |
max(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最大元素。 |
|
static <T extends Object & Comparable<? super T>> |
min(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最小元素。 |
package comwangxing.collectionstest;
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest {
public static void main(String[] args) {
//Collections类【集合类的帮助类】
//此类中的方法都是静态方法,静态方法为了帮助我们更加方便的操作集合中的数据。
ArrayList list1=new ArrayList();
list1.add(123);
list1.add(12);
list1.add(3);
list1.add(345);
for(Object obj:list1){
System.out.println("排序前--"+obj);
}
//static void sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。
Collections.sort(list1);
for(Object obj:list1){
System.out.println("排序后--"+obj);
}
//static void reverse(List<?> list) 反转指定列表中元素的顺序。
Collections.reverse(list1);
for(Object obj:list1){
System.out.println("反转后--"+obj);
}
//static T max(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最大元素。
System.out.println("最大元素--"+Collections.max(list1));
//static T min(Collection<? extends T> coll) 根据其元素的 自然顺序返回给定集合的最小元素。
System.out.println("最小元素--"+Collections.min(list1));
//static <T> void copy(List<? super T> dest, List<? extends T> src) 将所有元素从一个列表复制到另一个列表中。
ArrayList list2=new ArrayList();
list2.add("zhangsan");
list2.add("lisi");
list2.add("wangwu");
list2.add("zhaoliu");
list2.add("test");
/*
//源集合list2 == 目标集合list1 [源集合中的元素会覆盖目标集合中的元素]
Collections.copy(list1, list2);
for(Object obj:list1){
System.out.println("copy后--"+obj);
}
*/
/*
//源集合list2 < 目标集合list1 [源集合中的元素会覆盖目标集合中的元素,会有遗留]
Collections.copy(list1, list2);
for(Object obj:list1){
System.out.println("copy后--"+obj);
}
*/
//源集合list2 > 目标集合list1 [java.lang.IndexOutOfBoundsException]
Collections.copy(list1, list2);
for(Object obj:list1){
System.out.println("copy后--"+obj);
}
}
}
注意与Arrays的比较
4.Collection接口与Collections类的区别
Collection接口 |
Collections类 |
Interface |
Class |
包含了一些集合的基本操作方法【增删改查】 |
集合框架的帮助类对集合的排序,搜索以及序列化的操作 |