体系结构:双列集合的顶层接口
基础方法
1、V put(K key, V value):向集合中添加一个键值对对象,注意:如果向其中添加一个不存在的key,成功后会返回一个null;若向其中添加的key已经存在,则会返回被覆盖的那个对象的value值 2、V remove(Object key):根据键,删除集合中的元素 3、void clear():将集合清空 4、boolean containsKey(Object key):存在集合中是否存在某个key 5、boolean containsValue(Object value):存在集合中是否存在某个value 6、boolean isEmpty():判断集合是否为空,底层是用size来判断的 7、int size():获取集合的长度,也是集合中键值对的数量
put方法演示
@Test
void test3() {
// 1.创建集合
Map<String, Integer> map = new HashMap<>();
// 2.向集合中添加元素
Integer i1 = map.put("zhangsan", 23);
System.out.println(i1); // null
Integer i2 = map.put("zhangsan", 28);
System.out.println(i2); // 23
map.put("lisi", 30);
map.put("wangwu", 40);
// 3.查看集合中的元素
// {lisi=30, zhangsan=28, wangwu=40}
System.out.println(map);
}
由此可见,第一个键值对对象被第二个给覆盖掉了
Map集合的遍历方式
根据键查找值
@Test
void test4() {
// 1.创建集合
Map<String, Integer> map = new HashMap<>();
// 2.向集合中添加元素
map.put("zhangsan", 23);
map.put("lisi", 30);
map.put("wangwu", 40);
// 3.遍历集合方式1
// 拿到集合中的所有key的集合
Set<String> keys = map.keySet();
for (String key : keys) {
// lisi:30 zhangsan:23 wangwu:40
System.out.println(key + ":" + map.get(key));
}
}
根据键值对遍历
@Test
void test5() {
// 1.创建集合
Map<String, Integer> map = new HashMap<>();
// 2.向集合中添加元素
map.put("zhangsan", 23);
map.put("lisi", 30);
map.put("wangwu", 40);
// 3.遍历集合方式2
// 先获取到集合中所有的键值对集合,然后再遍历这个集合,依次取出键值对对象的键和值
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry: entries) {
// lisi:30 zhangsan:23 wangwu:40
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
使用lambda遍历
@Test
void test6() {
// 1.创建集合
Map<String, Integer> map = new HashMap<>();
// 2.向集合中添加元素
map.put("zhangsan", 23);
map.put("lisi", 30);
map.put("wangwu", 40);
// 3.遍历集合方式3,forEach底层是使用增强for进行遍历的,拿到每一个键值对对象,然后获取到这个对象的key和value,再传给方法accept,也就是我们在匿名内部类中重写的方法中
// 使用lambda进行遍历
// 匿名内部类的写法
map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
// lisi:30 zhangsan:23 wangwu:40
System.out.println(s + ":" + integer);
}
});
// 因为BiConsumer是一个函数式的接口,所以可以使用lambda进行简化
// lisi:30 zhangsan:23 wangwu:40
map.forEach((s, integer) -> System.out.println(s + ":" + integer));
}
具体案例
案例1:向集合中存储自定义对象,要求同姓名、同年龄是同一个学生
注意:实体类中需要重写equals和hashCode方法
实体类:Student.java
public class Student implements Comparable<Student>{
private String name;
private Integer age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
测试类:
@Test
void test7() {
// 1.创建集合
Map<Student, String> map = new HashMap<>();
Student zhangsan = new Student("zhangsan", 23);
Student lisi = new Student("lisi", 24);
Student wangwu = new Student("wangwu", 25);
Student wangwu2 = new Student("wangwu", 25);
// 2.向集合中添加元素
map.put(zhangsan, "浙江");
map.put(lisi, "上海");
map.put(wangwu, "北京");
map.put(wangwu2, "北京");
// 3.查看结果
// {Student(name=wangwu, age=25)=北京, Student(name=lisi, age=24)=上海, Student(name=zhangsan, age=23)=浙江}
System.out.println(map);
}
案例2:map中按照id的升序或降序排序,TreeMap
键:id,整数 值:字符串类型的 要求:map中按照id的升序或降序排序
升序排序
@Test
void test8() {
// 1.创建集合
TreeMap<Integer, String> treeMap = new TreeMap<>();
// 2.向集合中添加元素
treeMap.put(2, "啤酒");
treeMap.put(1, "西瓜");
treeMap.put(4, "可乐");
treeMap.put(3, "红酒");
// 3.查看结果,默认会按照升序进行排序,因为Integer中重写了compareTo方法:(x < y) ? -1 : ((x == y) ? 0 : 1);
// {1=西瓜, 2=啤酒, 3=红酒, 4=可乐}
System.out.println(treeMap);
}
但是如果想要按照id的降序,进行排序,那么Integer中的compareTo方法是不能满足我们的需求的,所以我们需要在创建集合的时候,传入一个比较器对象
降序排序
@Test
void test9() {
// 1.创建集合
TreeMap<Integer, String> treeMap = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// o1是当前要添加的元素
// o2是已经在红黑树中的元素
// 该返回值规则同TreeSet
// return o2 - o1;
return o2 - o1;
}
});
// 2.向集合中添加元素,在调用put的时候回去调用上面的compare方法
treeMap.put(2, "啤酒");
treeMap.put(1, "西瓜");
treeMap.put(4, "可乐");
treeMap.put(3, "红酒");
// 3.查看结果,此时会按照降序进行排序,因为在创建集合的时候指定了比较器
// {4=可乐, 3=红酒, 2=啤酒, 1=西瓜}
System.out.println(treeMap);
}
HashMap和TreeMap使用选择
如果没有要求元素存放的顺序的话,优先使用HashMap;如果要求按照指定的顺序存放元素的话,那么请使用TreeMap。