1、Map接口
public interface Map<K,V>
将键映射到值的对象,一个映射不能包含重复的键;每个键最多只能映射到一个值。
void clear() | 清空Map集合中的内容 |
---|---|
boolean containsKey(Object key) | 判断集合中是否存在指定的key |
boolean containsValue(Object value) | 判断集合中是否存在指定的value |
Set<Map.Entry<K,V>> entrySet() | 将Map接口变为Set集合 |
V get(Object key) | 根据key找到其对应的value |
boolean isEmpty() | 判断是否为空 |
---|---|
Set keySet() | 将全部的key变为Set集合 |
Collection values() | 将全部的value变为Collection集 |
合 | |
V put(K key,V value) | 向集合中增加内容 |
void putAll(Map<? extends K,? extendsV> m) | 增加一组集合 |
V remove(Object key) | 根据key删除内容 |
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/*
* Map接口
* 1、键值对存储一组对象
* 2、Key不能重复(唯一),Value可以重复
* 3、具体的实现类HashMap、TreeMap、Hashtable、LinkedHshMap
*/
public class MapDemo {
private static void hashMap() {
Map<Integer,String> map=new HashMap<Integer, String>();
map.put(1, "Tom");
map.put(2, "lily");
map.put(3, "viec");
map.put(4, "Bin");
System.out.println("size="+map.size());
//从Map中取值
System.out.println(map.get(1));//通过key来取值
//Map遍历
Set<Entry<Integer,String>> entrySet=map.entrySet();
for(Entry e:entrySet) {
System.out.println(e.getKey()+"->"+e.getValue());
}
System.out.println("·················");
//遍历建
Set<Integer> kyes=map.keySet();
for(Integer i:kyes) {
String value=map.get(i);
System.out.println(i+"->"+value);
}
System.out.println("·················");
//遍历值
Collection<String> values=map.values();
for(String value:values) {
System.out.println(value);
}
System.out.println("·················");
//forecah
map.forEach((key,value)->System.out.println(key+"->"+value));
}
public static void main(String[] args) {
hashMap();
}
}
size=4
Tom
1->Tom
2->lily
3->viec
4->Bin
1->Tom
2->lily
3->viec
4->Bin
Tom
lily
viec
Bin
1->Tom
2->lily
3->viec
4->Bin
2、HashMap
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。
(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映
射的顺序,特别是它不保证该顺序恒久不变。
/*
* HashMap的实现原理:
* 1、基于哈希表(数组+链表+二叉树(红黑树))jdk1.8
* 2、默认加载因子为0.75,默认数组大小为16
* 3、把对象存储到哈希表中,如何存储?
* 把key对象通过hash()方法计算hash值,然后用这个hash值对数组长度取余(默认为16)来决定对KEY对象
* 在数组中的存储位置,当这个位置有多个对象时,以链表结构来存储,jdk1.8之后,当链表长度大于8时,链表将转换为二叉树
* 红黑树结构存储。
* 这样的目的,为了取值更快,存储的数据量越大,性能的表现越明显
*
* 4、扩充原理,当数组的容量超过了75%,表示该数组需要扩充,如何扩充?
* 扩充的算法是,当前数组容量<<1相当于是乘以2,扩大一倍,扩充次数过多会影响性能,每次扩充表示哈希重新
* 散列(重新计算每个对象的存储位置),我们在开发中尽量减少扩充的次数
*
* 5、线程不安全,适合单线程使用
*/
3、Hashtable
public class Hashtable<K,V> extends Dictionary<K,V>
implements Map<K,V>, Cloneable, Serializable
此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。
为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。
4、LinkedHashMap
public class LinkedHashMap<K,V>
extends HashMap<K,V> implements Map<K,V>
Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处
在于,后者维护着一个运行于所有条目的双重链接列表。
5、TreeMap
public class TreeMap<K,V> extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, Serializable
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,
或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
/*
* 基于二叉树红黑树
*/
private static void treeMap() {
Map<String,String> map=new TreeMap<String, String>();
//map.put("one", "lily");
//map.put("tow", "Tom");
//map.put("three", "Bin");
//map.forEach((key,value)->System.out.println(key+"->"+value));
//自定义Dog class中要实现Comparable
Map<Dog,String> dogs=new TreeMap<>();
dogs.put(new Dog(1,"2ha",3),"dog1");
dogs.put(new Dog(2,"wangwang",2),"dog2");
dogs.put(new Dog(3,"hsq",4),"dog3");
dogs.forEach((key,value)->System.out.println(key+"->"+value));
//输出
//Dog [id=1, name=2ha, age=3]->dog1
//Dog [id=2, name=wangwang, age=2]->dog2
//Dog [id=3, name=hsq, age=4]->dog3
}
/*LinkedHashMap是 HashMap的子类,由于HashMap不能保证顺序恒久变,此类使用一个双重链表来维护
* 元素添加顺序
*
*/
private static void linkedHashMap() {
Map<String,String> table=new LinkedHashMap<String, String>();
table.put("one", "lily");
table.put("tow", "Tom");
table.put("three", "Bin");
table.forEach((key,value)->System.out.println(key+"->"+value));
}
/*
* jdk1.0开始
* 基于哈希表实现(数组+链表)
* 默认数组大小为11,加载因子0.75
* 扩充方法:原数组大小<<1(*2)+1
* 线程安全的,用在多线程访问时
*/
private static void hashtable() {
Map<String,String> table=new Hashtable<>();
table.put("one", "lily");
table.put("tow", "Tom");
table.put("three", "Bin");
table.forEach((key,value)->System.out.println(key+"->"+value));
}
1.8 Map接口的新方法:
在JDK8中Map接口提供了一些新的便利的方法。因为在本文中我所提到的所有Map方法都是以
默认值方法的方式实现的,所以现有的Map接口的实现可以直接拥有这些在默认值方法中定
义的默认行为,而不需要新增一行代码。
getOrDefault(Object, V)
putIfAbsent(K,V)
remove(Object key, Object value)
replace(K,V)
replace(K,V,V)
compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)
merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)