集合框架-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.test1;
import java.util.HashMap;
public class HashMaptest1 {
public static void main(String[] args) {
//构造方法:
/*
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<Object, Object> hsm1=new HashMap<Object, Object>();
HashMap hsm2=new HashMap<>(30);
HashMap hsm3=new HashMap<>(30,0.5f);
HashMap hsm4=new HashMap<>(hsm1);
}
}
实例方法:
- 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.test1;
import java.util.HashMap;
public class HashMaptest2 {
public static void main(String[] args) {
//HashMap的实例方法
/*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集合中
*/
//创建HashMap构造方法
HashMap hhm1=new HashMap();
//添加键值对数据
hhm1.put("hello", 123);
hhm1.put("world", 123);
hhm1.put(123, "hello");
hhm1.put(123, "world");
hhm1.put("hello", "world");
//boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println("集合中是否有hello键?"+hhm1.containsKey("hello"));
//boolean containsValue(Object key) 判断集合中是否包含指定的值
System.out.println("集合中是否有hello值?"+hhm1.containsValue("hello"));
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("根据指定的hello键得到该键对应的值"+hhm1.get("hello"));
//boolean isEmpty() 判断集合是否为空
System.out.println("集合是否为空?"+hhm1.isEmpty());
//int size() 得到集合中键值对元素的个数
System.out.println("键值对元素个数:"+hhm1.size());
//V remove(Object key) 根据指定的键删除对应的键值对数据值
hhm1.remove("123");
}
}
遍历集合:
package com.wangxing.test1;
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) {
/*
* Set keySet() 得到集合中所有的键保存到Set集合中
* Collection values() 得到集合中所有的值保存到Collection集合中
* Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
*/
//遍历HashMap
//创建HashMap构造方法
HashMap<Object,Object> hhm1=new HashMap<Object,Object>();
//添加键值对数据
hhm1.put("hello", 123);
hhm1.put("world", 123);
hhm1.put(123, "hello");
hhm1.put(123, "world");
hhm1.put("hello", "world");
//遍历集合中所有的键
Set setkey=hhm1.keySet();
for(Object key:setkey){
System.out.println("键=="+key);
}
System.out.println("------------------");
Iterator it =setkey.iterator();
while (it.hasNext()) {
System.out.println("键=="+it.next());
}
System.out.println("------------------");
//遍历集合中所有的值
Collection coll1=hhm1.values();
for(Object key:coll1){
System.out.println("值=="+key);
}
System.out.println("------------------");
Iterator it1= coll1.iterator();
while (it1.hasNext()) {
System.out.println("值=="+it1.next());
}
System.out.println("------------------");
//遍历集合中所有的键值
Set entrset= hhm1.entrySet();
for(Object ob:entrset){
System.out.println(ob);
}
System.out.println("------------------");
for(Map.Entry<Object, Object> entry:hhm1.entrySet()){
entry.getKey();
entry.getValue();
System.out.println("键值对=="+entry.getKey()+":"+entry.getValue());
}
}
}
2.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.test2;
import java.util.Hashtable;
public class testHashtable1 {
public static void main(String[] args) {
//Hashtable
//构造方法:
/*
Hashtable() 构造一个新的,空的散列表,默认初始容量(11)和负载因子(0.75)。
Hashtable(int initialCapacity) 构造一个新的,空的哈希表,具有指定的初始容量和默认负载因子(0.75)。
Hashtable(int initialCapacity, float loadFactor) 构造一个新的,空的哈希表,具有指定的初始容量和指定的负载因子。
Hashtable(Map<? extends K,? extends V> t) 构造一个与给定地图相同的映射的新哈希表。
*/
Hashtable hhm1=new Hashtable();
Hashtable hhm2=new Hashtable(30);
Hashtable hhm3=new Hashtable(30,0.5f);
Hashtable hhm4=new Hashtable(hhm1);
}
}
实例方法:
- 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 com.wangxing.test2;
import java.util.Hashtable;
public class testHashtable2 {
public static void main(String[] args) {
//实例方法
/*
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() 返回此散列表中值的枚举。
*/
//创建对象
Hashtable hhm1=new Hashtable();
//Object put(Object key, Object value) 向集合中添加键值对数据
hhm1.put("hello", 123);
hhm1.put(123,"hello" );
hhm1.put("world", 456);
hhm1.put(456,"world" );
//boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println("是否有hello键?"+hhm1.containsKey("hello"));
//boolean containsValue(Object value) 判断集合中是否包含指定的值
System.out.println("是否有hello值?"+hhm1.containsValue("hello"));
//Object get(Object key) 根据指定的键得到该键对应的值
System.out.println("根据hello键得到值=="+hhm1.get("hello"));
//boolean isEmpty() 判断集合是否为空。
System.out.println("是否为空?"+hhm1.isEmpty());
//int size() 得到集合中键值对元素的个数
System.out.println("键值对的个数:"+hhm1.size());
//V remove(Object key) 根基指定的键删除对应的键值对数据值
hhm1.remove(123);
//boolean isEmpty() 判断集合是否为空。
System.out.println("是否为空?"+hhm1.isEmpty());
//void clear() 清空集合。
hhm1.clear();
System.out.println("验证是否清空=="+hhm1.size());
}
}
遍历集合:
package com.wangxing.test2;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class testHashtable3 {
public static void main(String[] args) {
//遍历Hashtable
//创建对象
Hashtable<Object, Object> hhm1=new Hashtable<Object, Object>();
//Object put(Object key, Object value) 向集合中添加键值对数据
hhm1.put("hello", 123);
hhm1.put(123,"hello" );
hhm1.put("world", 456);
hhm1.put(456,"world" );
/*
Set keySet() 得到集合中所有的键保存到Set集合中
Collection values() 得到集合中所有的值保存到Collection集合中
Set<Map.Entry<K,V>> entrySet() 得到集合中所有的键值对数据Set集合中
Enumeration<K> keys() 返回此散列表中键的枚举。
Enumeration<V> elements() 返回此散列表中值的枚举。
*/
//遍历集合中所有的键
Set setkey=hhm1.keySet();
for(Object ob1:setkey){
System.out.println("键=="+ob1);
}
System.out.println("-----------------");
//迭代器
Iterator iterator=setkey.iterator();
while(iterator.hasNext()){
System.out.println("键=="+iterator.next());
}
System.out.println("------------------");
//遍历集合中所有的值
Collection collection=hhm1.values();
for(Object ob2:collection){
System.out.println("值=="+ob2);
}
System.out.println("------------------");
//迭代器
Iterator iterator1=collection.iterator();
while(iterator1.hasNext()){
System.out.println("值=="+iterator1.next());
}
System.out.println("-------------------");
//遍历集合键值对
Set setentry=hhm1.entrySet();
for(Object ob3:setentry){
System.out.println("键值对:"+ob3);
}
System.out.println("--------------------");
for(Map.Entry<Object, Object> map: hhm1.entrySet()){
map.getKey();
map.getValue();
System.out.println("键值对=="+map.getKey()+":"+map.getValue());
}
}
}
TreeMap类–红黑树基于NavigableMap实现【有序】
ConcurrentHashMap类—线程安全,支持高并发,哈希表
3.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接口) |
线程不安全 | 线程安全 | 线程不安全 |
4.认识Collections类【集合类的帮助类】
public class Collections----此类仅由静态方法组合或返回集合
此类中的方法都是静态方法,静态方法为了帮助我们更加方便的操作集合中的数据。
static <T extends Comparable<? super T>> sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。
void static void reverse(List<?> list) 反转指定列表中元素的顺序。
static <T> 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 com.wangxing.test3;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class TestCollections1 {
public static void main(String[] args) {
//Collections类
/*
此类仅由静态方法组合或返回集合
此类中的方法都是静态方法,静态方法为了帮助我们更加方便的操作集合中的数据
*/
//静态方法:
/*
static <T extends Comparable<? super T>> sort(List<T> list) 根据其元素的natural ordering对指定的列表进行排序。
void static void reverse(List<?> list) 反转指定列表中元素的顺序。
static <T> 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) 根据其元素的 自然顺序返回给定集合的最小元素。
*/
//创建ArrayList对象
ArrayList arr1=new ArrayList();
//添加数据
arr1.add("zhangsan");
arr1.add("lisi");
arr1.add("wangwu");
arr1.add("zhaoliu");
//通过Collections来排序
Collections.sort(arr1);
//查看
System.out.println("排序后:");
for(Object obj:arr1) {
System.out.println(obj);
}
//反转arr1 集合
System.out.println("反转后:");
Collections.reverse(arr1);
for(Object obj1:arr1){
System.out.println(obj1);
}
//返回最大值
//创建新集合
ArrayList arr2=new ArrayList();
arr2.add(123);
arr2.add(23);
arr2.add(4567);
arr2.add(2);
System.out.println("最大值:"+Collections.max(arr2));
System.out.println("最小值:"+Collections.min(arr2));
System.out.println("集合1复制给集合2");
//复制到另一个集合
//将集合1复制给集合2
Collections.copy(arr2, arr1);
for(Object ob3:arr2){
System.out.println(ob3);
}
}
}