目录
4.2 HashMap案例2:键Integer值String
4.3 HashMap案例3:键String值Student
4.4 HashMap案例4:键Student值String
6.1 TreeMap案例1:键是String值是String
6.2 TreeMap案例2:键是Student值是String
7.2 List、Set、Map等接口是否都继承自Map接口?
7.3 Collection和Collections的区别?
1.Map集合的特点
- 将键映射到值的对象
- 一个映射不能包含重复的键
- 每个键最多只能映射到一个值
2.Map集合的功能概述
2.1 添加功能
- V put(K key,V value):添加元素
2.2 删除功能
- V remove(Object key):根据键删除键值对元素,并返回值
- void clear():移除所有的键值对元素
2.3 判断功能
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
2.4长度功能
- int size():返回集合中键值对的对数
2.5获取功能
- Set<K> keySet():获取集合中所有键的集合
- V get(Object key):根据键获取值
- Collection<V> values():获取集合中所有值的集合
- Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
3.Map集合的遍历
3.1 根据键找值
分析步骤如下:
- 获取所有的键
- 遍历键的集合,获取得到每一个键
- 根据键去找值
部分代码如下:
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// 向集合中添加元素
map.put("杨过", "小龙女");
map.put("杨康", "穆念慈");
map.put("郭靖", "黄蓉");
map.put("杨玄风", "梅超风");
// 获取集合中所有键的集合
Set<String> set = map.keySet();
// 遍历set,得到每一个key
for (String key : set) {
// 根据键去找值
String value = map.get(key);
System.out.println(key + "---" + value);
}
3.2 根据键值对对象找键和值
分析步骤如下:
- 获取所有键值对对象的集合
- 循环遍历键值对对象的集合,得到每一个键值对对象
- 根据键值对对象得到键和值
部分代码如下:
// 创建集合对象
Map<String, String> map = new HashMap<String, String>();
// 向集合中添加元素
map.put("杨过", "小龙女");
map.put("杨康", "穆念慈");
map.put("郭靖", "黄蓉");
map.put("杨玄风", "梅超风");
// 获取键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
// 循环遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry<String, String> entry : entrySet) {
// 根据键值对对象得到键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "---" + value);
}
4.HashMap的概述
- HashMap是基于哈希表的Map接口的实现。
- 哈希表的作用是用来保证的键的唯一性的。
- 哈希表结构底层依赖hashcode()方法和equals()方法!
4.1 HashMap案例1:键String值String
// 创建集合对象
HashMap<String, String> hm = new HashMap<String, String>();
// 向集合中添加元素
hm.put("allan", "男");
hm.put("bella", "女");
hm.put("zhangsan", "女");
// 遍历
// 获取所有键的集合
Set<String> set = hm.keySet();
for (String key : set) {
// 根据键去找值
String value = hm.get(key);
System.out.println(key + "---" + value);
}
4.2 HashMap案例2:键Integer值String
// 创建集合对象
HashMap<Integer, String> hm = new HashMap<Integer, String>();
// 向集合中添加元素
hm.put(28, "allan");
hm.put(2, "bella");
hm.put(28, "zhangsan");
hm.put(27, "allan");
// 遍历
// 获取所有键的集合
Set<Integer> set = hm.keySet();
for (Integer key : set) {
// 根据键找值
String value = hm.get(key);
System.out.println(key + "---" + value);
}
4.3 HashMap案例3:键String值Student
Student.java的代码:
public class Student {
private String name;
private int age;
public Student() {
super();
}
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;
}
}
// 创建集合对象
HashMap<String, Student> hm = new HashMap<String, Student>();
// 创建学生对象
Student s1 = new Student("allan", 27);
Student s2 = new Student("bella", 2);
Student s3 = new Student("zhangsan", 28);
Student s4 = new Student("allan", 27);
// 向集合中添加元素
hm.put("spring001", s1);
hm.put("spring006", s2);
hm.put("spring002", s3);
hm.put("spring008", s4);
// 遍历
// 获取所有键的集合
Set<String> set = hm.keySet();
for (String key : set) {
Student s = hm.get(key);
System.out.println(key + "---" + s.getName() + "---" + s.getAge());
}
4.4 HashMap案例4:键Student值String
要求:如果两个对象的成员变量值都相同,则为同一个对象。
分析:HashMap是基于哈希表的Map接口的实现,而哈希表的底层依赖hashcode()方法和equals()方法。在Student类中并没有重写这两个方法,所以默认使用的Object类的hashcode()和equals()方法,这时候学生对象的hash值是不一样的,所以所有的学生对象都会输出!
解决方法:在Student类中重写hashcode()方法和equals()方法!
Student.java代码如下:
package com.hw.map02;
public class Student {
private String name;
private int age;
public Student() {
super();
}
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 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;
}
}
测试类代码如下:
// 创建集合对象
HashMap<Student, String> map = new HashMap<Student, String>();
// 创建学生对象
Student s1 = new Student("貂蝉", 27);
Student s2 = new Student("王昭君", 30);
Student s3 = new Student("西施", 33);
Student s4 = new Student("杨玉环", 35);
Student s5 = new Student("貂蝉", 27);
// 添加元素
map.put(s1, "三国");
map.put(s2, "汉朝");
map.put(s3, "春秋战国");
map.put(s4, "唐朝");
map.put(s5, "隋朝");
// 获取集合中所有键的集合
Set<Student> set = map.keySet();
for (Student stu : set) {
String value = map.get(stu);
System.out.println(stu.getName() + "---" + stu.getAge() + "---" + value);
}
运行结果如下:
貂蝉---27---隋朝
西施---33---春秋战国
杨玉环---35---唐朝
王昭君---30---汉朝
5.LinkedHashMap的概述和使用
LinkedHashMap是Map接口的哈希表和链接的实现,具有可预知的迭代顺序。
- 由哈希表保证键的唯一性
- 由链表保证键的有序(存储和取出的顺序一致)
LinkedHashMap保证了记录的插入顺序,在遍历LinkedHashMap时,先得到的记录是先插入的!
部分代码如下:
// 创建集合对象
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
// 向集合中添加元素
map.put("spring_001", "hello");
map.put("spring_003", "world");
map.put("spring_001", "javaee");
map.put("spring_002", "hello");
map.put("spring_003", "html");
map.put("spring_004", "javascript");
// 获取集合中键的集合
Set<String> set = map.keySet();
for (String key : set) {
String value = map.get(key);
System.out.println(key + "---" + value);
}
运行结果如下:
spring_001---javaee
spring_003---html
spring_002---hello
spring_004---javascript
6.TreeMap概述
TreeMap是基于二叉树的Map接口的实现。
键是二叉树结构,可以保证键的排序和唯一性!
下面来看两个TreeMap的案例!
6.1 TreeMap案例1:键是String值是String
// 创建集合对象
// 当构造方法为空时,使用自然排序进行排序
TreeMap<String, String> tm = new TreeMap<String, String>();
// 向集合中添加元素
tm.put("liangchaowei", "刘嘉玲");
tm.put("dengchao", "孙俪");
tm.put("huangxiaoming", "杨颖");
tm.put("zhangjie", "谢娜");
tm.put("huangxiaoming", "范冰冰");
// 遍历
Set<String> set = tm.keySet();
for (String key : set) {
String value = tm.get(key);
System.out.println(key + "---" + value);
}
运行结果如下:
dengchao---孙俪
huangxiaoming---范冰冰
liangchaowei---刘嘉玲
zhangjie---谢娜
6.2 TreeMap案例2:键是Student值是String
Student.java代码如下:
package cn.itcast_04;
public class Student {
private String name;
private int age;
public Student() {
super();
}
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;
}
}
TreeMapDemo2.java代码如下:
package com.hw.map02;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
/**
* TreeMap:键是二叉树结构,可以保证键的排序和唯一性
*
* TreeMap<Student, String>
* 键:Student
* 值:String
*
* 使用比较器排序,按照年龄从小到大排序
*
* @author HW
*
*/
public class TreeMapDemo2 {
public static void main(String[] args) {
// 创建集合对象
// 当一个方法的参数是接口时,真正需要的是该接口实现类的对象
TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {
public int compare(Student s1, Student s2) {
int num1 = s1.getAge() - s2.getAge();
int num2 = (num1 == 0) ? (s1.getName().compareTo(s2
.getName())) : num1;
return num2;
}
});
// 创建学生对象
Student s1 = new Student("allan", 27);
Student s2 = new Student("bella", 3);
Student s3 = new Student("ella", 28);
Student s4 = new Student("bella", 2);
Student s5 = new Student("allan", 27);
// 向集合中添加元素
tm.put(s1, "男");
tm.put(s2, "女");
tm.put(s3, "女");
tm.put(s4, "男");
tm.put(s5, "女");
// 获取集合中键的集合
Set<Student> set = tm.keySet();
for (Student stu : set) {
String value = tm.get(stu);
System.out.println(stu.getName() + "---" + stu.getAge() + "---" + value);
}
}
}
运行结果如下:
bella---2---男
bella---3---女
allan---27---女
ella---28---女
7.面试题
7.1 Hashtable和HashMap的区别?
- Hashtable:线程安全,效率低。不允许null键和null值
- HashMap:线程不安全,效率高。允许null键和null值
7.2 List、Set、Map等接口是否都继承自Map接口?
- List、Set不是继承自Map接口,它们继承自Collection接口
- Map接口本身就是一个顶层接口
7.3 Collection和Collections的区别?
- Collection:是单列集合的顶层接口,有子接口List和Set。
- Collections:是针对集合操作的工具类,都是静态方法,包括对集合进行排序和二分查找的方法