目录
一,Map接口概述
查看Map API可以知道:
1,将键映射到值的对象
2,一个映射不能包含重复的键
3,每个键最多只能映射到一个值
Map接口和Collection接口的区别
1,Map是双列的,Collection是单列的
2,Map的键唯一,Collection的子体系Set是唯一的
3,Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效
二,Map中的方法
int size() //返回此双列集合中键值映射的数量。
boolean isEmpty()//判断集合是否为空
boolean containsKey(Object key)//判断集合是否包含指定的键
boolean containsValue(Object value)//判断集合是否包含指定的值
V get(Object key) //返回到指定键所映射的值,或null如果此映射包含该键的映射。
V put(K key,V value) //添加元素。
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
void clear()//移除所有的键值对元素
V remove(Object key)//根据键删除键值对元素,并把值返回
Set<Map.Entry<K,V>> entrySet() //Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
V get(Object key) //根据键获取值
Set<K> keySet() //获取集合中所有键的集合
Collection<V> values() //获取集合中所有值的集合
三,Map集合之遍历
1,通过keySet()遍历
private static void demo1() {
Map<String,Integer> map = new HashMap();
map.put("张无忌", 30);
map.put("赵敏", 33);
map.put("周芷若", 20);
map.put("张三丰",99);
Collection<Integer> c = map.values();
System.out.println(c);
//第一种遍历
Set<String> s = map.keySet();
Iterator<String> i = s.iterator();
while(i.hasNext()){
// System.out.println(i.next());
String key = i.next();
System.out.println(key +" = " + map.get(key));
}
//增强for循环遍历,能用迭代器的遍历,一定能用增强for循环
for (String key : map.keySet()) {
System.out.println("key = "+key +" ; "+" value = " + map.get(key));
}
}
运行结果:
[99, 33, 20, 30]
张三丰 = 99
赵敏 = 33
周芷若 = 20
张无忌 = 30
key = 张三丰; value = 99
key = 赵敏; value = 33
key = 周芷若; value = 20
key = 张无忌; value = 30
2,通过 entrySet()方法遍历
public static void main(String[] args) {
// demo1();
Map<String,Integer> map = new HashMap();
map.put("张无忌", 30);
map.put("赵敏", 33);
map.put("周芷若", 20);
map.put("张三丰",99);
Set<Map.Entry<String, Integer>> en = map.entrySet();
Iterator<Map.Entry<String, Integer>> i = en.iterator();
//while 循环
while(i.hasNext()){
Map.Entry<String, Integer> me = i.next();
String key = me.getKey();
Integer value = me.getValue();
System.out.println(key + " = " + value);
}
//增强for循环,能用迭代器遍历的一定能用增强for循环
for (Map.Entry<String, Integer> entry : en) {
System.out.println(entry.getKey() + "= "+ entry.getValue());
}
}
运行结果:
张三丰 = 99
赵敏 = 33
周芷若 = 20
张无忌 = 30
--------------------------------------------------------
张三丰= 99
赵敏= 33
周芷若= 20
张无忌= 30
四,子类
4.1,HashMap
HashMap中的键是唯一的,采用哈希算法来保证键的唯一;那么如果键是自定义对象,如需保证键的唯一,就要重写自定义对象的hashCode方法和equals方法;
例如HashMap存储Student对象:
public static void main(String[] args) {
HashMap<Student,String> hashMap = new HashMap<>();
hashMap.put(new Student("张无忌",20), "金庸");
hashMap.put(new Student("张三丰",30), "金庸");
hashMap.put(new Student("张无忌",20), "金庸");
System.out.println(hashMap);
}
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
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 "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
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 (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
打印信息:
没有重写hashCode和equals方法的打印输出
{Student [name=张无忌, age=20]=金庸, Student [name=张无忌, age=20]=金庸, Student [name=张三丰, age=30]=金庸}
重写 hashCode和equals方法的打印输出
{Student [name=张三丰, age=30]=金庸, Student [name=张无忌, age=20]=金庸} //去掉了重复的Student对象
4.2,LinkedHashMap
LinkedHashMap的键底层采用的是链表的数据结构实现的,所以有个特性就是:怎么存就怎么取,即存入的顺序和取出来的顺序是一样的;
4.3,TreeMap
TreeMap的键采用的是二叉树的数据结构实现键的唯一;
如果需要存储自定义对象并且按照一定条件排序(排列顺序),
1,实现Comparable中的compareTo方法,在此方法中实现具体排序逻辑;
2,创建TreeMap对象的时候构造方法中传一个Comparator<? super K> ,Comparator可以是匿名内部类,也可以是实现类,总之都是在重写compare方法中实现排序的逻辑;