Map集合
1 Map集合基础:概述、基本操作、Map 分类
1.1 Map集合概述
Map集合实现了这样一件事:存储键值对,一对一对存入,同时保证键的唯一性
1.2 Map集合基本操作
基本操作中,需要说明的是entrySet()、keySet()操作,因为Map集合没有迭代器,所以需要转换成为别的类型进行获取。
1,添加。
put(K key, V value)
putAll(Map<? extends K,? extends V> m)
2,删除。
clear()
remove(Object key)
3,判断。
containsValue(Object value)
containsKey(Object key)
isEmpty()
4,获取。
get(Object key)
size()
values()
5,两种获取的方法。
entrySet()
keySet()
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String, String>();
System.out.println("1 put:"+map.put("01", "wzy"));
map.put("02","wzy02");
map.put("03","wzy03");
map.put("04","wzy04");
map.put("05","wzy04");
map.put("05","hahahhaha"); // 问题1:相同键对应不同值时?
map.put("06",null); // 问题2:键值对是否可以为空?
map.put(null, "wzy06");
map.put(null, null);
System.out.println("2 containsKey:"+map.containsKey("022"));
System.out.println("3 containsKey:"+map.containsKey("03"));
System.out.println("4 get:"+map.get("021"));
System.out.println("5 get:"+map.get("02"));
Collection<String> col = map.values(); // 获得值
System.out.println(col);
System.out.println(map); // 打印全部
}
}
打印结果:
1 put:null // put方法会返回两个值(1)当键相同而值不同,返回被覆盖的值(2)当没有相同键时,返回null
2 containsKey:false
3 containsKey:true
4 get:null
5 get:wzy02
[null, wzy, wzy02, wzy03, wzy04, hahahhaha, null]
{null=null, 01=wzy, 02=wzy02, 03=wzy03, 04=wzy04, 05=hahahhaha, 06=null}
- hashmap 问题1:添加相同的键?
添加相同的键,之前的值会被新值覆盖掉 - hashmap 问题2:键值对是否可以为空?
HashMap允许使用 null 值和 null 键,Hashtable不可以存入null键null值 - hashmap 问题3:获取值与对?
可以使用keySet存储键,使用.get(Object obj)找到值;或者entrySet中的.getKey()获取键,.getValue()获取值; - hashmap 问题4:取出键方式(1)keyset (2)entryset?
见下文 - hashmap 问题5:一个取出元素的例子,用不同的方法实现
见下文
1.3 分类
什么时候使用map集合?当对象之间存在着映射关系时,就要先想到map集合?
- Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
- HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高,要保证键的唯一性,需要覆盖hashCode方法,和equals方法。
- TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。需要使用Comparable或者Comparator进行比较排序。return 0,来判断键的唯一
2 Map集合的两种取出方式:
原因,Map集合没有自己的迭代器,需要将它转换到Set类型,调用Set类型的迭代器。
2.1 keySet
keySet:做法是用集合存储集合的键,将map中的所有键存入到Set集合,因为Set具备迭代器,以可以迭代的方式取出所有键,通过get()方法取出值。
// keySet 取出元素键
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String, String>();
map.put("01","wzy01");
map.put("02","wzy02");
map.put("03","wzy03");
map.put("04","wzy04");
//键合集获取,使用set集合,因为有迭代器
Set<String> keySet = map.keySet();
Iterator<String> it = keySet.iterator();
while (it.hasNext())
{
String key = it.next();
// 值获取
String value = map.get(key);
System.out.println("key: "+key+"...."+"value: "+value);
}
}
}
2.2 entrySet
entrySet:做法是存储集合的关系,这个关系被定义为了Map.Entry<K,V>类型,
// Map.Entry<,> 实现元素取出
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapDemo3 {
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String, String>();
map.put("01","wzy01");
map.put("02","wzy02");
map.put("03","wzy03");
map.put("04","wzy04");
map.put("05","wzy05");
// 关系取出Map.Entry<K,V> 这是一个类
//
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
while (it.hasNext())
{
Map.Entry<String,String> me = it.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key+" : "+value);
}
}
}
2.3 一个取出元素的例子
// 任务描述:
// 1)建立Student类,记录每个对象的姓名与年龄;
// 2)使用Student类作为键,使用地址信息作为值;
// 3)储存在HashMap中,使用keySet()进行取出、使用entrySet()进行取出
import java.util.*;
public class MapTest {
public static void main(String[] args)
{
HashMap<Student,String> hm = new HashMap<Student,String>();// 建立类存储对象
hm.put(new Student("wzy01",21),"shanxi");
hm.put(new Student("wzy02",22),"kunming");
hm.put(new Student("wzy03",23),"fuzhou");
hm.put(new Student("wzy04",24),"xiamen");
hm.put(new Student("wzy05",25),"haerbin");
// 取出方式1:keySet()
Set<Student> keySet = hm.keySet();
Iterator<Student> it = keySet.iterator();
while (it.hasNext())
{
Student stu = it.next();
String addr = hm.get(stu);// 使用键获得值
System.out.println(stu+".."+addr);
}
System.out.println("- - - - - 分割线 - - - - -");
// 取出方式2:entrySet()
Set<Map.Entry<Student,String>> out = hm.entrySet();
Iterator<Map.Entry<Student,String>> it2 = out.iterator();
while (it2.hasNext())
{ // 指定对象类型 对象形参 = 迭代器.方法()
Map.Entry<Student,String> out2 = it2.next();
Student stu2 = out2.getKey();
String addr2 = out2.getValue();
System.out.println(stu2+"..."+addr2);
}
}
}
class Student implements Comparable<Student> //实现方法 compareTo()
{
private String name;
private int age;
Student(String name,int age)
{
this.age = age;
this.name = name;
}
public int hashCode() // 实现方法hashCode
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj) // 实现方法equals
{
if(!(obj instanceof Student))
throw new ClassCastException("Can`t Match The Class Sir!");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age==s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public int compareTo(Student s) // 实现方法3
{
int num = new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public String toString()
{
return name+":"+age;
}
}
// 关于程序的一些说明:
一、 关于对象Student建立
(1)其中继承了接口 Comparable,所以第一件事需要复写compareTo()方法,因为如果Student对象实体变多后,会把这些实体存放在二叉树结构中,所以是为二叉树的比较创建方法。
(2)Student对象是需要传入HashMap中的,看到HashMap与HashSet相近,底层都是哈希表,所以需要实现在HashSet中出现的方法hashCode()、equals();
PS:TreeSet中出现的是:继承Comparable,底层是二叉树数据结构,需要实现方法compareTo()方法进行比较;
二、关于对象Student的取出方式
(1)HashMap的键为学生类,而学生类有两个参数
(2)HashMap的值为地域字符串
(3)获取方式分为两种,keySet()方法获得了键集合,通过键找到了值
(4)entrySet()方法获得了存储的关系,把它定义为了一个新类:Map.Entry<K,V>