一、Map集合介绍
Map集合:java.util.Map<k,v>
双列集合,将键(k)映射到值(v)的对象,键是唯一的,值可以不唯一,每个键只能映到一个值。
注意事项:
1.Map集合一个元素包含两个值(key和value),一个(key,value)称为一个键值对,而且key和value一一对应。
2.Map集合key是唯一的,即一个Map集合对象中同一个key只能出现一次的,value可以重复出现,集合无序。
3.Map集合中key和value的类型可以相同,也可以不同,都可以为Java已经定义好的类型和自定义类型。
二、Map接口常用方法
public V put(K key,V value):把指定的键和值存入到指定的Map集合中。
public V remove(Object key):把指定的键所对应的键值对进行删除,并返回被删除元素的值。
public V get(Object key):根据指定的键,在Map中获取对应的值。
public boolean containsKey(Object key):判断集合中是否包含指定的键。
public Set keySet():获取Map集合中所有的键,存储到Map集合中
public Set<Map.Entry<K,V>> entrySet():获取到Map集合所有键值对对象的集合。
注意:Map接口不能直接创建使用,可以使用Map的常用子类进行HashMap和LinkedHashMap使用 .
public class MapDemo01 {
public static void main(String[] args) {
//使用多态创建Map对象,key和value数据类型相同
Map<String,String> map=new HashMap<>();
/*public V put(K key,V value):把指定的键和值存入到指定的Map集合中
*如果添加的键K不重复,则返回值为null
*如果添加的键K集合中已经存在,则对应的新的值V会替换掉集合已经存在的值,并返回被替换的值
*一般使用中返回值可以不用接收
*/
String value1=map.put("孙行者", "孙悟空");
System.out.println(value1);//输出结果:null
String value2=map.put("天蓬元帅", "猪八戒");
System.out.println(value2);//输出结果:null
String value3=map.put("孙行者", "齐天大圣孙悟空");
System.out.println(value3);//输出结果:孙悟空
System.out.println(map);//输出结果:{天蓬元帅=猪八戒, 孙行者=齐天大圣孙悟空} 也是无序集合
map.put("唐僧", "唐三藏");
map.put("沙僧", "卷帘大将");
System.out.println(map);//输出结果:{天蓬元帅=猪八戒, 沙僧=卷帘大将, 孙行者=齐天大圣孙悟空, 唐僧=唐三藏}
/* public V remove(Object key):把指定的键所对应的键值对进行删除,并返回被删除元素的值
*key存在,返回key对应的value
*key不存在,返回null
*/
String value4 = map.remove("沙僧");
System.out.println(value4);//输出结果:卷帘大将
System.out.println(map);//输出结果:{天蓬元帅=猪八戒, 孙行者=齐天大圣孙悟空, 唐僧=唐三藏}
String value5 = map.remove("红孩儿");//不存在的key
System.out.println(value5);//输出结果:null
/*public V get(Object key):根据指定的键,在Map中获取对应的值
*key存在,返回对应的value
*key不存在,返回null
*/
String value6 = map.get("唐僧");
System.out.println(value6);//输出结果:唐三藏
String value7 = map.get("红孩儿");//不存在的key
System.out.println(value7);//输出结果:null
/*
public boolean containsKey(Object key):判断集合中是否包含指定的键
*key存在,返回true
*key不存在,返回false
*/
boolean key1 = map.containsKey("天蓬元帅");
System.out.println(key1);//输出结果:true
boolean key2 = map.containsKey("红孩儿");//不存在的key
System.out.println(key2);//输出结果:false
//使用多态创建Map对象,key和value数据类型不同同
Map<String,Integer> map1=new HashMap<>();
//操作方法和上面相同,下面以put方法进行说明
map1.put("孙悟空", 1);
map1.put("猪八戒", 2);
map1.put("唐僧", 3);
map1.put("沙僧", 4);
System.out.println(map1);//输出结果:{沙僧=4, 孙悟空=1, 猪八戒=2, 唐僧=3}
}
}
三、通过keySet()进行集合遍历
public Set keySet():获取Map集合中所有的键,存储到Map集合中。
Map集合第一种遍历方法:通过指定的键找对应的值
1.Java已经定义好的数据类型
使用方法:
1.创建Map对象,并添加数据
2.使用Map中keySet()方法,将键存储到Set集合中去
3.使用迭代器方法或者增强for循环,通过key值,遍历对应的value值。
2.自定义数据类型
使用方法:
1.必须重写hashCode方法和equals方法,因为要保证key值的唯一性,Java定义好的类型已经 重写了hashCode方法和equals方法,所以可以直接用。
2.创建Map对象,创建自定义类对象,并添加数据。
3.使用Map中keySet()方法,将键存储到Set集合中去。
4.使用迭代器方法或者增强for循环,通过key值,遍历对应的value值。
public class MapDemo02 {
public static void main(String[] args) {
//Java已经定义好的数据类型
//使用多态创建Map对象
Map<String,String> map=new HashMap<>();
map.put("孙行者", "孙悟空");
map.put("天蓬元帅", "猪八戒");
map.put("唐僧", "唐三藏");
map.put("沙僧", "卷帘大将");
System.out.println(map);//输出结果:{天蓬元帅=猪八戒, 沙僧=卷帘大将, 孙行者=孙悟空, 唐僧=唐三藏}
//使用Map中keySet()方法,将键存出到集合中去
Set<String> set=map.keySet();
Iterator<String> it=set.iterator();
//使用迭代器方法或者增强for循环,通过key值,遍历对应的value值
//使用迭代器
while(it.hasNext()){
String key=it.next();
System.out.print(key+"="+map.get(key)+",");//输出结果:天蓬元帅=猪八戒,沙僧=卷帘大将,孙行者=孙悟空,唐僧=唐三藏,
}
//使用增强for循环
for(String key:set){
System.out.print(key+"="+map.get(key)+",");//输出结果:天蓬元帅=猪八戒,沙僧=卷帘大将,孙行者=孙悟空,唐僧=唐三藏,
}
System.out.println("========================================================");
// 自定义数据类型
//使用多态创建Map对象,创建自定义类对象,添加数据
Map<Student,String> map1=new HashMap<>();
Student stu1=new Student(101,"孙悟空");
Student stu2=new Student(102,"猪八戒");
Student stu3=new Student(103,"唐僧");
Student stu4=new Student(104,"沙僧");
map1.put(stu1, "孙行者");
map1.put(stu2, "天蓬元帅");
map1.put(stu3, "唐三藏");
map1.put(stu4, "卷帘大将");
map1.put(stu4, "沙悟净");//添加一个与上一个相同的对象,以便做相同的key值检验
System.out.println(map1);/*没有重写hashCode和equals方法的输出结果:Student [stuNo=103, stuName=唐僧]=唐三藏, Student [stuNo=104, stuName=沙僧]=沙悟净, Student [stuNo=101, stuName=孙悟空]=孙行者, Student [stuNo=102, stuName=猪八戒]=天蓬元帅,
Student [stuNo=104, stuName=沙僧]=卷帘大将} 不能保证key的唯一性
重写hashCode和equals方法的输出结果:{Student [stuNo=102, stuName=猪八戒]=天蓬元帅, Student [stuNo=103, stuName=唐僧]=唐三藏, Student [stuNo=104, stuName=沙僧]=沙悟净, Student [stuNo=101, stuName=孙悟空]=孙行者}
*/
}
}
//自定义的类
class Student{
private int stuNo;
private String stuName;
public Student(int stuNo, String stuName) {
super();
this.stuNo = stuNo;
this.stuName = stuName;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
@Override
public String toString() {
return "Student [stuNo=" + stuNo + ", stuName=" + stuName + "]";
}
//重写hashCode和equals方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((stuName == null) ? 0 : stuName.hashCode());
result = prime * result + stuNo;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (stuName == null) {
if (other.stuName != null)
return false;
} else if (!stuName.equals(other.stuName))
return false;
if (stuNo != other.stuNo)
return false;
return true;
}
}
四、通过entrySet()进行集合遍历
public Set<Map.Entry<K,V>> entrySet():获取到Map集合所有键值对对象的集合。
Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在集合中是一一对应的关系,这一对对象(key,value)
又称Map集合的一个Entry(映射项),Entry将键值对的对应关系分装成了对象,即键值对对象,这样我们在遍历Map集合时,就 可以从每一个键值对(Entry)对象中获取对应键和对应值的方法:
public K getKey():获取Entry对象中的值
public V getValue():获取Entry对象中的值
遍历Map集合的第二种方式:使用键值对对象Entry进行遍历
1.Java已经定义好的数据类型
使用方法:
1.创建Map对象,并添加数据
2.使用Map中entrySet()方法,将键存储到Set集合中去
3.使用迭代器方法或者增强for循环,通过getKey()和getValue()进行遍历
2.自定义数据类型
使用方法:
1.必须重写hashCode方法和equals方法,因为要保证key值的唯一性,Java定义好的类型已经重写了hashCode方法和equals方法,所以可以直接用。
2.创建Map对象,并添加数据。
3.使用Map中entrySet()方法,将键存储到Set集合中去。
4.使用迭代器方法或者增强for循环,通过getKey()和getValue()进行遍历。
public class MapDemo03 {
public static void main(String[] args) {
//Java已经定义好的数据类型
//使用多态创建Map对象
Map<String,String> map=new HashMap<>();
map.put("孙行者", "孙悟空");
map.put("天蓬元帅", "猪八戒");
map.put("唐僧", "唐三藏");
map.put("沙僧", "卷帘大将");
System.out.println(map);//输出结果:{天蓬元帅=猪八戒, 沙僧=卷帘大将, 孙行者=孙悟空, 唐僧=唐三藏}
//使用Map中entrySet()方法,将键存储到Set集合中去
Set<Map.Entry<String,String>> set= map.entrySet();
//使用迭代器方法或者增强for循环,通过getKey()和getValue()进行遍历
Iterator<Map.Entry<String,String>> it = set.iterator();
while(it.hasNext()){
Map.Entry<String,String> next=it.next();
String key=next.getKey();
String value=next.getValue();
System.out.print(key+"="+value+",");//输出结果:天蓬元帅=猪八戒,沙僧=卷帘大将,孙行者=孙悟空,唐僧=唐三藏,
}
}
}
五、Map常用子类
Map常用子类:
HashMap集合:java.util.HashMap<K,V>
1.底层是哈希表, 查询速度快。
JDK1.8之前:哈希表:链表+数组。
JDK1.8以后:哈希表:链表+数组/红黑树(链表长度超过8)。
2.hashMap集合是一个无序的集合,存储元素和取出元素不一致。
LinkedHashMap集合:java.util.LinkedHashMap<K,V>
1.底层是哈希表+链表(保证顺序)
2.是一个有序的集合
Hashtable集合:java.util.Hashtable<K,V>
1.底层是哈希表,查询速度慢.
2.不能存储null键和null值.
3.双列集合的最初形态,从JDK1.0就开始,但从JDK1.2和Vector集合一样被取代.
public class MapDemo04 {
public static void main(String[] args) {
//使用多态创建Map对象
Map<Integer,String> map=new HashMap<>();
map.put(1, "孙悟空");
map.put(3, "猪八戒");
map.put(2, "唐三藏");
map.put(4, "卷帘大将");
map.put(4, "沙僧");
System.out.println(map);//输出结果:{1=孙悟空, 2=唐三藏, 3=猪八戒, 4=沙僧} 无序集合且key不能重复
LinkedHashMap<Integer,String> map1=new LinkedHashMap<>();
map1.put(1, "孙悟空");
map1.put(3, "猪八戒");
map1.put(2, "唐三藏");
map1.put(4, "卷帘大将");
map1.put(4, "沙僧");
System.out.println(map1);//输出结果:{1=孙悟空, 3=猪八戒, 2=唐三藏, 4=沙僧} 有序集合且key不能重复
//Hashable集合
HashMap<Integer,String> map2=new HashMap<>();
map2.put(null, "孙悟空");
map2.put(3, null);
map2.put(null, null);
System.out.println(map2);//输出结果:{null=null, 3=null} 容许存储空值
Hashtable<Integer,String> hash=new Hashtable<>();
// hash.put(null, "孙悟空");
// hash.put(3, null);
// hash.put(null, null);
// System.out.println(hash);会报错,hashtable不能存储空值
}
}