1.双列集合:
Map<K,V>集合的特点:K用来限制键的类型,V用来限制值的类型
1.Map集合存储元素是以键值对的形式存储,每一个键值对都有键和值
2.Map集合的键是唯一,值可以重复,如果键重复了,那么值就会被覆盖
3.根据键来取值
Map集合子类:
- HashMap<K,V> 存储数据采用的哈希表结构,元素的存取顺序不能保证一致
由于要保证键的唯一,不重复,需要重写键的hashCode方法,equals方法
- LinkedHashMap<K,V> HashMap下的子类,存储数据采用的是哈希表结构 + 链表结构
通过链表结构可以保证键值对的存取顺序一致
通过哈希表结构可以保证键的唯一,不重复,需要重写键的hashCode方法,equals方法
- TreeMap<K,V> TreeMap集合和Map相比没有特有的功能,底层的数据结构都是红黑树
可以对元素的键进行排序,排序方式有两中:自然排序和比较器排序
2.Map的常用方法
- public V put(K key, V value) 把指定的键与指定的值添加到Map集合中
- public V remove(Object key) 把指定的键所对应的键值对元素 在Map集合中删除,返回被删除的元素的值
- public V get(Object key) 根据指定的键,在Map集合中获取对应的值
- public boolean containsKey(Object key) 判断该集合中是否包含有此键
- public boolean containsValue(Object value) 判断该集合中是否包含有此值
- public Set<K> keySet() 获取Map集合中所有的键,存储到Set集合中
- public Collection<V> values() 获取Map集合中所有的值,存储到Collection集合中
- public Set<Map.Entry<K,V>> entrySet() 获取到Map集合中所有的键值对 对象的集合(Set集合)
- public static interface Map.Entry<K,V> 表示键值对对象 --- 把键值对包装成一个对象,该对象类型就是Entry类型
// 创建Map集合,限制键的类型为String,值的类型为Integer
Map<String,Integer> map = new HashMap<>();
map.put("张三",20);
map.put("李四",21);
map.put("王五",22);
System.out.println(map); // {李四=21, 张三=20, 王五=22}
// Map集合键唯一,如果键重复了,值会覆盖
Integer s1 = map.put("李四", 30); // 21
System.out.println(s1);
System.out.println(map); // {李四=30, 张三=20, 王五=22}
// Map集合值可以重复
Integer s2 = map.put("赵六", 50);
System.out.println(s2); // null
System.out.println(map); // {李四=30, 张三=20, 王五=22, 赵六=50}
// 删除 李四 键对应的这个键值对
Integer s3 = map.remove("李四");
System.out.println(s3); // 30
System.out.println(map); // {张三=20, 王五=22, 赵六=50}
// 获取 张三 键对应的值
Integer s4 = map.get("张三");
System.out.println(s4);
// 判断是否包含指定的键
boolean b1 = map.containsKey("张三");
System.out.println(b1); // true
boolean b2 = map.containsKey("小明");
System.out.println(b2); // false
//获取所有的键
Set<String> key = map.keySet();
System.out.println(key); //[张三, 王五, 赵六]
//获取所有的值
Collection<Integer> values = map.values();
System.out.println(values); // [20, 22, 50]
// 获取Map集合中所有的键值对对象
Set<Map.Entry<String, Integer>> entries = map.entrySet();
System.out.println(entries); // [张三=20, 王五=22, 赵六=50]
3.Map遍历
方式一:
1.获取Map集合所有的键
2.循环遍历Map集合所有的键
3.在循环中,根据键找值
// 创建Map集合,限制键的类型为String,值的类型为String
Map<String,Integer> map = new HashMap<>();
//往 map集合中添加键值对
map.put("张三",20);
map.put("李四",21);
map.put("王五",22);
// 方式一:根据键找值
// 1.获取Map集合所有的键
Set<String> strings = map.keySet();
// 2.循环遍历Map集合中所有的键
for (String keys : strings) {
// 3.在循环中,根据键找值
Integer value = map.get(keys);
System.out.println(keys+"=="+value);
方式二:键值对对象的形式
1.获取Map集合中所有的键值对 对应的 键值对对象 entrySet() 方法
2.循环遍历所有的键值对对象
3.根据键值对对象获取键和值
Entry<K,V>接口:简称Entry项,表示键值对 对象,用来封装Map集合中的键值对
Entry<K,V>接口:Map接口中的内部接口,在外部使用的时候是这样表示的
Map.Entry<K,V>
Map.Entry<K,V>接口中的API:
- K getKey(); 获取键值对对象包装的键
- V getValue(); 获取键值对对象包装的值
// 创建Map集合,限制键的类型为String,值的类型为String
Map<String,Integer> map = new HashMap<>();
map.put("张三",20);
map.put("李四",21);
map.put("王五",22);
//方式二:键值对对象的形式
//1.获取Map集合中所有的键值对 对应的 键值对对象 entrySet() 方法
Set<Map.Entry<String, Integer>> entries = map.entrySet();
System.out.println(entries);
// 2.循环遍历所有的键值对对象
for (Map.Entry<String, Integer> entry : entries) {
//3.根据键值对对象获取键和值
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"=="+value);
}
4.HashMap存储自定义类型
public class Student {
String name ;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + 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 age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
class Tests {
public static void main(String[] args) {
// 创建HashMap集合,限制键的类型为Student,值的类型为String
Map<Student, String> map = new HashMap<>();
// 往集合中添加键值对
Student s1 = new Student("张三", 15);
Student s2 = new Student("李四", 50);
Student s3 = new Student("王五", 17);
Student s4 = new Student("赵六", 41);
Student s5 = new Student("孙七", 19);
Student s6 = new Student("张三", 15);
map.put(s1,"上海");
map.put(s2,"深圳");
map.put(s3,"郑州");
map.put(s4,"兰州");
map.put(s5,"四川");
map.put(s6,"北京");
System.out.println(map);
System.out.println(map.size());
}
}
5.LinkedHashMap
元素存取有序,键唯一,值可重复
- 通过链表结构保证元素存取有序,顺序一致
- 通过哈希表结构可以保证键的唯一,不重复,需要复写hashCode方法和equals方法
// 创建LinkedHashmap对象,限制键的类型为Integer,值的类型为String
LinkedHashMap<Integer,String> map = new LinkedHashMap<>();
map.put(300,"山西");
map.put(100,"陕西");
map.put(500,"郑州");
map.put(200,"四川");
map.put(400,"北京");
System.out.println(map);
6.TreeMap集合
键唯一,值可重复,如果键重复了,值会覆盖
- public TreeMap() 根据键按照默认规则进行排序
- public TreeMap(Comparator<? super K> comparator) 通过比较器指定规则排序
// 默认规则:升序
TreeMap<Integer,String>map = new TreeMap<>();
map.put(300,"山西");
map.put(100,"陕西");
map.put(500,"郑州");
map.put(200,"四川");
map.put(400,"北京");
System.out.println(map);
// 降序
TreeMap<Integer,String>map1 = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
map1.put(300,"山西");
map1.put(100,"陕西");
map1.put(500,"郑州");
map1.put(200,"四川");
map1.put(400,"北京");
System.out.println(map1);