Map集合笔记
一、Map集合的特点
-
Map集合是一个双列集合
-
Map中的元素,key和value的数据类型可以相同,也可以不同。
-
Map中的元素,key是允许重复的,value是可以重复的
-
Map中的元素,key和value是一一对应的。
二、Map集合与Collection集合的区别
-
Collection中的元素是孤立存在的。
-
Map中的元素是成对存在的。每个元素由键与值两部分组成,通过键可以找到对应额值。
-
Map集合不能直接使用迭代器或者增强循环,但是转成Set集合之后可以使用迭代器和增强循环。
三、Map集合的常用方法
-
public V put(K key , V value):添加元素,若key不存在则返回null;若key存在则返回替换之前的值,并把原来的值替换为参数值。
-
public V remove(Object key):删除
-
public V get(Object key):获取指定键对应的值
-
public set<k> keySet():获取Map集合中的所有的值,存储到Set集合中。
-
public set<Map.Entry<K,v> > entrySet():获取到Map集合中所有的键值对对象的Set集合。
-
public containsKey(Object key):判断集合中是否包含指定的键。
四、Map集合的常用子类
-
HashMap:存储数据采用哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写hashCode方法和equals方法。
-
LinkedHashMap:extends HashMap 。存储数据采用哈希表+链表结构。通过链表结构可以保证元素的存取顺序一致。通过哈希表结构可以保证键的唯一、不重复。需要重写hashCode方法和equals方法。
-
Properties:java.util.Properties<String ,String v> extends Hashtable<K,V> implements Map<K,V> 。唯一一个与IO流结合的集合,表示了一个持久的属性集。Java中的File类与常用IO流,第七章 Properties
五、重写hashCode方法与equals方法
- 1 @Override
- 2 public boolean equals(Object o) {
- 3 if (this == o)
- 4 return true;
- 5
- 6 if (o == null || getClass() != o.getClass())
- 7 return false;
- 8
- 9 Student student = (Student) o;
- 10 return age == student.age && Objects.equals(name,student.name);
- 11 }
- 1 @Override
- 2 public int hashCode() {
- 3 return Objects.hash(name, age);
- 4 }
六、Map集合遍历键找值方式
步骤:
-
用keySet获取所有的键存储到Set集合中
-
遍历存储键的Set集合,得到每一个键
-
用get(K key),根据键获取对应的值。
代码演示:
- 1 //创建Map集合对象
- 2 HashMap<String, String> map = new HashMap<String,String>();
- 3 //添加元素到集合
- 4 map.put("一班", "大明");
- 5 map.put("二班", "二明");
- 6 map.put("三班", "三明");
- 7
- 8 //第一步,获取所有的键 获取键集
- 9 Set<String> keys = map.keySet();
- 10 //第二步, 遍历键集 得到 每一个键
- 11 for (String key : keys) {
- 12 //第三部,获取对应值
- 13 String value = map.get(key);
- 14 System.out.println(key+"的:"+value);
- 15 }
七、Entry键值对对象
Map中存放的是两种对象,一种为key ,一种为 value ,它们在 Map中是一一对应的关系,这一对对象又称作 “Map中的一个项(Entry)”。Entry将键值对的对应关系封装成了对象。即键值对对象。
-
public Set<Map.Entry<K,V> > entrySet():获取map集合所有键值对的对象的Set集合。
-
public K getKey():获取Entry对象中的键
-
public V getValue():获取Entry对象中的值
注意:Map集合不能直接使用迭代器或者增强循环进行遍历,但是转成
Set之后就可以使用了。
八、Map集合遍历键值对方式
步骤:
-
获取Map集合中,所有的键值对对象(Entry),以Set集合的方式返回;
-
遍历Set集合,得到每一个键值对对象;
-
通过键值对对象,获取键值对中的键getKey()与值getValue()。
代码示例:
- 1 // 创建Map集合对象
- 2 HashMap<String, String> map = new HashMap<String,String>();
- 3 // 添加元素到集合
- 4 map.put("一班", "大明");
- 5 map.put("二班", "二明");
- 6 map.put("三班", "三明");
- 7
- 8 // 获取 所有的 entry对象 entrySet
- 9 Set<Entry<String,String>> entrySet = map.entrySet();
- 10
- 11 // 遍历得到每一个entry对象
- 12 for (Entry<String, String> entry : entrySet) {
- 13 // 解析
- 14 String key = entry.getKey();
- 15 String value = entry.getValue();
- 16 System.out.println(key+"的:"+value);
- 17 }
九、HashMap存储自定义类型键值
- 1 public class Student {
- 2 private String name;
- 3 private int age;
- 4
- 5 public Student() {
- 6 }
- 7
- 8 public Student(String name, int age) {
- 9 this.name = name;
- 10 this.age = age;
- 11 }
- 12
- 13 public String getName() {
- 14 return name;
- 15 }
- 16
- 17 public void setName(String name) {
- 18 this.name = name;
- 19 }
- 20
- 21 public int getAge() {
- 22 return age;
- 23 }
- 24
- 25 public void setAge(int age) {
- 26 this.age = age;
- 27 }
- 28
- 29 @Override
- 30 public boolean equals(Object o) {
- 31 if (this == o)
- 32 return true;
- 33 if (o == null || getClass() != o.getClass())
- 34 return false;
- 35 Student student = (Student) o;
- 36 return age == student.age && Objects.equals(name, student.name);
- 37 }
- 38
- 39 @Override
- 40 public int hashCode() {
- 41 return Objects.hash(name, age);
- 42 }
- 43 }
- 1 public class HashMapTest {
- 2 public static void main(String[] args) {
- 3 //1,创建Hashmap集合对象。
- 4 Map<Student,String>map = new HashMap<Student,String>();
- 5 //2,添加元素。
- 6 map.put(newStudent("lisi",28), "上海");
- 7 map.put(newStudent("wangwu",22), "北京");
- 8 map.put(newStudent("zhaoliu",24), "成都");
- 9 map.put(newStudent("zhouqi",25), "广州");
- 10 map.put(newStudent("wangwu",22), "南京");
- 11
- 12 //3,取出元素。键找值方式
- 13 Set<Student>keySet = map.keySet();
- 14 for(Student key: keySet){
- 15 Stringvalue = map.get(key);
- 16 System.out.println(key.toString()+"....."+value);
- 17 }
- 18 }
- 19 }
* 当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须复写对象的hashCode和equals方法。
* 如果要保证map中存放的key和取出的顺序一致,可以使用`java.util.LinkedHashMap`集合来存放。
十、LinkedHashMap
HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?
在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构。
代码示例:
- 1 public class LinkedHashMapDemo {
- 2 public static void main(String[] args) {
- 3 LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
- 4 map.put("一班", "大明");
- 5 map.put("三班", "三明");
- 6 map.put("二班", "二明");
- 7 Set<Entry<String, String>> entrySet = map.entrySet();
- 8 for (Entry<String, String> entry : entrySet) {
- 9 System.out.println(entry.getKey() + " " + entry.getValue());
- 10 }
- 11 }
- 12 }
运行结果显示,存取顺序是一致的。
十一、集合补充:JDK9对集合添加的优化
在没有使用集合工厂之前,通常要添加几个元素,就要几次add方法或put方法。
使用集合工厂:方便创建少量元素的集合、map实例:
-
List.of(str1,str2,str3);
-
Set.of(str1,str2,str3);
-
Map.of(str1,str2,str3);
注意:
-
of() 方法只是 List、Set、Map 这三个接口的静态方法,其父类接口或子类接口并没有这类方法,比如 HashSet ,ArrayList 等等。
-
返回的集合是不可变的。