Java 集合(四) Map
Map 集合是一种 双列集合
,每个元素包含 两个数据
。
Map 集合的每个元素的格式:key = value
(键值对元素),其中 key 是唯一的
。
Map 集合也被称为 `键值对集合 。
Map 常用API
方法名称 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V get(Object key) | 根据键找值 |
Set keySet() | 获得所有键的集合 |
entrySet() | 获取所有键值对对象的集合 |
Set<Map.Entry<K,V>> entrySet() | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
Map 集合实现类的特点
HashMap
:元素按照键是无序,不重复,无索引,值不做要求。(与Map体系一致)
LinkedHashMap
:元素按照键是有序,不重复,无索引,值不做要求。
TreeMap
:元素按照建是排序,不重复,无索引的,值不做要求。
Map 集合的遍历
-
方式一:键找值的方式遍历:先获取 Map 集合全部的键,再根据遍历键找值。
-
方式二:键值对的方式遍历,把「键值对」看成一个整体,难度较大。
-
方式三:JDK 1.8开始之后的新技术:Lambda表达式。
方式一:键找值
步骤:
- 第一步:使用 keyset 方法获取所有的键
- 第二步:使用 get 方法根据键找到对应的值
public class MapIterationByKey {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new HashMap<>();
// 为对象添加元素
map.put("apple", 15);
map.put("orange", 13);
map.put("banana", 17);
// 根据键找值
// 第一步:获取所有的键
Set<String> keys = map.keySet();
// 第二步:根据键找值
for (String key : keys){
System.out.println("key = " + key + "; value = " + map.get(key));
}
}
}
输出结果:
key = orange; value = 13
key = banana; value = 17
key = apple; value = 15
方式二:键值对放入 Set 中遍历
步骤:
-
第一步:先使用
entrySet()
方法把 Map 集合转换成 Set 集合,Set 集合中每个元素都是键值对实体类型了。 -
第二步:遍历 Set 集合,然后提取键以及提取值。
Map.Entry
接口中提供的 API
方法 | 返回值 |
---|---|
K getKey() | 获得键 |
V getValue() | 获取值 |
public class MapIterationByKV {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new HashMap<>();
// 为对象添加元素
map.put("apple", 15);
map.put("orange", 13);
map.put("banana", 17);
// 第一步:通过 entrySet 方法将 Map 存入 Set 中去
Set<Map.Entry<String, Integer>> entries = map.entrySet();
// 第二步:遍历 Map
for (Map.Entry<String, Integer> entry : entries) {
System.out.println("key = " + entry.getKey() + "; value = " + entry.getValue());
}
}
}
方法三:使用 Lambda 表达式遍历
public class MapIterationByLambda {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new HashMap<>();
// 为对象添加元素
map.put("apple", 15);
map.put("orange", 13);
map.put("banana", 17);
// 使用 Lambda 表达式遍历
map.forEach((k, v) -> System.out.println("key = " + k + "; value = " + v));
}
}
HashMap
HashMap 跟 HashSet 底层原理是一模一样的,都是哈希表结构,只是 HashMap 的每个元素包含两个值而已。
HashMap 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
LinkedHashMap
HashSet 有一个 LinkedHashSet 子类,HashMap 也有一个 LinkedHashMap 子类;LinkedHashMap 使用 双向链表
来维护 key-value 对的次序。
public class UseLinkedHashMap {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new LinkedHashMap<>();
// 为对象添加元素
map.put("apple", 15);
map.put("orange", 13);
map.put("banana", 17);
// 输出元素
System.out.println(map);
}
}
输出结果:
{apple=15, orange=13, banana=17}
由输出结果可以看出,LinkedHashMap 的 输出顺序和输入顺序一致
。
TreeMap
TreeMap 是一个 有序的key-value集合
,它是通过 红黑树
实现的,每个 key-value 对即作为红黑树的一个节点。
TreeMap 有两种排序方式,和 TreeSet 一样。
-
默认排序
-
定制排序
- 类实现 Comparable 接口,重写比较规则。
- 集合自定义 Comparator 比较器对象,重写比较规则。
TreeMap 排序之默认排序
- 对于数值类型的 key:Integer , Double,官方默认按照大小进行升序排序。
- 对于字符串类型的 key:默认按照首字符的编号升序排序。
public class UseTreeMapSortByDefault {
public static void main(String[] args) {
// 创建一个 HashMap 对象
Map<String, Integer> map = new TreeMap<>();
// 为对象添加元素
map.put("apple", 15);
map.put("orange", 13);
map.put("banana", 17);
// 输出集合
System.out.println(map);
}
}
输出结果:
{apple=15, banana=17, orange=13}
由输出结果可以看出,数值型的 key 根据 ASCII 码进行排序。
TreeMap 排序之类中实现 Comparable 接口
步骤:
- 第一步:创建一个学生类,并实现
comparable
- 第二步:在主调函数中创建一个 TreeMap 对象
// 创建一个学生类,实现 Comparable 接口
public class Student implements Comparable<Student> {
private String name;
private int age;
// 重写 compareTo 方法,按照年龄升序排序
@Override
public int compareTo(Student stu) {
return this.getAge() - stu.getAge();
}
// 有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// 无参构造器
public Student() {
}
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 +
'}';
}
}
主调方法如下:
public class UseTreeMapSortByCompareable {
public static void main(String[] args) {
// 创建一个 TreeMap 对象
Map<Student, Integer> map = new TreeMap<>();
// 为集合添加数据
map.put(new Student("Alex", 12), 1);
map.put(new Student("Leo", 23), 5);
map.put(new Student("Dore", 18), 3);
// 输出数据
System.out.println(map);
}
}
输出结果:
{Student{name=‘Alex’, age=12}=1, Student{name=‘Dore’, age=18}=3, Student{name=‘Leo’, age=23}=5}
由输出结果可以看出,是按照 Key 的年龄升序排序的。
Tree Map 排序之自定义 Compare 比较器
public class UseTreeMapSortByInterface {
public static void main(String[] args) {
// 创建一个 HashMap 对象,实现构造器并按降序排序
Map<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
// 为对象添加元素
map.put(15, "apple");
map.put(13, "orange");
map.put(17, "banana");
// 输出元素
System.out.println(map);
}
}
使用 Lambda 表达式
public class UseTreeMapSortByInterface {
public static void main(String[] args) {
// 创建一个 HashMap 对象,使用 Lambda 表达式并按降序排序
Map<Integer, String> map = new TreeMap<>( (o1, o2) -> {return o2 - o1;} );
// 为对象添加元素
map.put(15, "apple");
map.put(13, "orange");
map.put(17, "banana");
// 输出元素
System.out.println(map);
}
}