Map 接口:保存一对对象的最大父接口
Map集合的特点:
1,双列集合,一个元素包含两个集(key,value)键值对;
2,key,value 数据类型可以不同,也可以不同。
3,key值不允许重复 key值唯一
4,key->value(value可重复) 当Key值重复时,覆盖value值
1 .子类
1.1 HashMap
java.util.HashMap<k,v> implements Map<k,v>
1.1.1 HashMap特点:
1,HashMap 集合底层是哈希表:查询的速度特别快
Jdk 1.8之前 数组+单向链表
Jdk 1.8之后 数组+单向链表/红黑树(链表长度超过8)提高查询速度
2,HashMap集合是无序集合:储存,取出元素的顺序有可能不一致
3,线程不安全,速度较块
4,允许存放null值
1.1.2 HashMap内部实现
HashMap可以看作是数组(Node[] table)和链表结合组成的复合结构,数组被分为一个个桶。通过哈希值决定了键值对在这个数组的寻址;哈希值相同的键值对,则以链表的形式存储。如果链表大小超过阈值,链表就会被改造为树形结构。
1.2 LinkedHashMap
java.util.LinkHashMap<k,v> extends HashMap<k,v>
1.2.1 LinkedHashMap 特点
1,LinkedHashMap集合底层是哈希表+链表(链表用来记录元素的顺序)
2,LinkedHashMap 集合是一个有序的集合,存储元素和取出元素的顺序是一致的
3,key不允许重复
1.3 Hashtable
1.3.1 特点
1,key,value 不允许重复
2,最早期的双列集合 (jdk1.0)
3,线程安全,速度较慢
4,不允许存放null值,若存放null,会产生NullPointerException
5,无序集合,存取顺序不一致
Hashtable 和 Vector集合 在jdk1.2之后被更先进的集合(HashMap,ArrayList)取代,但Hashtable的子类Properties依旧在使用,它是唯一一个与I/O流相结合的集合。
package HashtableTest;
import java.util.Hashtable;
import java.util.Map;
/**
* @Name: 使用hashtable
* @Author:ZYJ
* @Date:2019-07-20-10:54
* @Description:
*/
public class HashtableTest {
public static void main(String[] args) {
Map<Integer,String> table = new Hashtable<>();
table.put(1,"A");
table.put(2,"B");
table.put(3,"C");
System.out.println(table);//{3=C, 2=B, 1=A}
}
}
1.4 HashMap与Hashtable的区别
No | 区别 | HashMap | HashTable |
---|---|---|---|
1 | 版本 | JDK1.2 | JDK1.0 |
2 | 性能 | 异步处理,性能高 | 同步处理,性能低 |
3 | 安全性 | 非线程安全 | 线程安全 |
4 | NULL | 允许存放 | 不允许存放 |
5 | 重复性 | 不允许重复 | 不允许重复 |
6 | 有序性 | 无序 | 无序 |
2. 方法
2.1 向Map中添加数据
添加元素,k不重复返回null,若k存在用新的value 替换旧value。返回被替换的value
public v put(K,V);
2.2 根据key取得对应的value,
如果可以存在,返回对应的value
如果不存在,返回null
public v get(Object key);
2.3 取得所有key信息,key不能重复
public Set<K> keySet();
Map集合中的所有key取出来存储到Set集合中
2.4 取得所有value信息,可以重复
public Collection<V> values();
2.5 将Map集合变为Set集合
public Set<Map ,Entry<k,y>> entrySet();
2.6 删除键值对
通过key删除键值对,若key存在,返回被删除的value;若key不存在,返回null;
public v remove(Object k);
2.7 判断是否包含键值对
如果此映射包含指定键的映射关系,则返回 true。
public boolean containsKey(Object key);
3. Map集合的遍历:
3.1,通过键找值的方式
3.1.1 实现步骤:
1,使用keySet()把Map集合中的所有key取出来存储到Set集合中。
2,使用迭代器/增强for循环遍历Set集合,获取Map集合的每一个Key。
3,通过get(key)可以获取value
package MapTest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @Name:遍历Map集合
* @Author:ZYJ
* @Date:2019-07-19-15:59
* @Description:
*/
public class MapTestDemo {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "Aamda");
map.put(2, "Dabe");
map.put(3, "xianxian");
//1,使用keySet()把Map集合中的所有key取出来存储到Set集合中。
Set<Integer> set = map.keySet();
//2,使用迭代器/增强for循环遍历Set集合,获取Map集合的每一个Key。
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
// 3,通过get(key)可以获取value
String value = map.get(key);
System.out.println(value + ":" + key);
}
//使用增强for()进行遍历
for(Integer key : map.ketSet()){
String value = map.get(key);
System.out.println(value+":"+key);
}
}
}
3.2 ,使用Entry对象遍历
Map集合中的方法 Set<Map.Entry<k,v>> entrySet(),返回此映射关系的Set视图
3.2.1 实现步骤
1,使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中。
2,遍历Set集合,获取每一个Entry对象
3,使用Entry对象中的方法 getKey()和getValue( )获取键与值。
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1,"A");
map.put(2,"B");
map.put(3,"C");
//1,使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中。
Set<Map.Entry<Integer,String>> set = map.entrySet();
//2,遍历Set集合,获取每一个Entry对象
Iterator<Map.Entry<Integer,String>> iterator =set.iterator();
//使用迭代器遍历
while (iterator.hasNext()){
Map.Entry<Integer,String> entry=iterator.next();
//3,使用Entry对象中的方法 getKey()和getValue( )获取键与值。
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
//使用增强for循环遍历Set集合
for(Map.Entry<Integer,String> entry : set){
Integer key = entry.getKey();
String value =entry.getValue();
System.out.println(key+"="+value);
}
}
4. Map集合中储存自定义键值
用户可采用自定义类作为key ,为了保证Key是唯一的,作为Key元素此时要覆写Object类中的hashCode()和equals()
package MapTest;
/**
* @Name: 自定义类做为键值
* @Author:ZYJ
* @Date:2019-07-20-09:58
* @Description:
*/
import java.util.*;
/**
* 自定义Person类并设置属性
* 为保证Key唯一,在Person类中覆写 HashCode()和 equals()方法
*/
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//覆写hashCode()和equals()以保证key唯一
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return getAge() == person.getAge() &&
Objects.equals(getName(), person.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
}
public class PersonKey {
public static void main(String[] args) {
Map<Person, String> map = new HashMap<>();
map.put(new Person("Amanda", 21), "程序员");
map.put(new Person("Dabe", 20), "研究僧");
map.put(new Person("Spring", 23), "老师");
map.put(new Person("Amanda", 21), "攻城狮");
//遍历map集合
/**
* 使用Entry对象遍历
*/
//1,使用entrySet()将Map集合转为Set集合
Set<Map.Entry<Person, String>> set = map.entrySet();
//2,获取迭代器
Iterator<Map.Entry<Person, String>> iterator = set.iterator();
//3,取出每一个key和value
while (iterator.hasNext()) {
Map.Entry<Person, String> entry = iterator.next();
Person key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "-->" + value);
}
/**
* 使用增强for循环遍历
*/
for(Map.Entry<Person,String> entry :set){
Person key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"-->"+value);
}
}
}
5. JDK1.9新特性
JDK1.9之后,List、Set、Map接口定义了一个静态工厂方法,可以一次性给集合添加多个元素。
public static <E> list<E> of()(E...elements);
5.1 使用前提
当集合中存储的元素个数已经确定,不再改变时使用。
5.2 注意
1,of()方法只实用于List、Set、Map接口,不适用与接口的实现类,否则会抛出异常
2,of()方法的返回值是一个不可改变的集合,不能再使用add/put添加元素,否则会抛出异常
3,Set,Map接口在调用of()时,不能有重复元素,否则会抛出异常
package NewOfTest;
import java.util.*;
/**
* @Name: of()的使用
* @Author:ZYJ
* @Date:2019-07-20-15:00
* @Description:
*/
public class NewOfTestDemo {
public static void main(String[] args) {
/* List<String> list = List.of("A","B","C");
list.add("D");
System.out.println(list);//抛出java.lang.UnsupportedOperationException异常*/
/*Set<String> set = Set.of("A","B","A","C");
System.out.println(set);//抛出java.lang.IllegalArgumentException异常*/
List<String> list = List.of("A","B","C","D");
System.out.println(list);//[A, B, C, D]
Set<Integer> set = Set.of(1,2,3,4,5);
System.out.println(set);//[4, 3, 2, 1, 5]
Map<Integer,String> map = Map.of(1,"Amanda",2,"Dabe",3,"Spring");
System.out.println(map);//{2=Dabe, 1=Amanda, 3=Spring}
}
}