30.Map双列集合

补充:对于基本数据类型,为了尽量避免空指针异常,多使用包装类!

集合不能装(Map是key)基本数据类型

一、Map双列集合

单列集合与双列集合的比较

  • Collection中,元素孤立存在;
  • Map中:
    • 1.成双成对儿,一一对应。
    • 2.键key不能重复,值value能重复
    • 3.根据key可以找到对应的value

HashTable下面有个子类Properties和IO流结合使用。

1. Map常用子类

  • HashMap :哈希表实现,(键就是HashSet)

    • 不同步(HashTable是同步的,效率低,不允许null键和null值;HashMa允许,但是null键只能出现一次)
    • 存取无序
    • 键唯一,需要重写hashMap()方法,equals()方法
  • LinkedHashMap :HashMap的一个子类

    • 存取结构为哈希表结构(保证键唯一)+链表结构(保证存取一致)
    • 需要重写hashMap()方法,equals()方法

2. Map接口中常用的方法(省略public)

  • V put(K key, V value): 把键值对添加到Map集合中,返回被替换之前的值,没有就是null
  • V remove(Object key): 删除键值对,返回被删除的value
  • V get(Object key): 根据键获取值
  • boolean containsKey(Object key) :是否包含该key
  • Set keySet(): 获取Map中所有的键,存在Set集合中。一般用于遍历
  • Set entrySet():获取到Map集合中多有的键值对对象的集合。
  • Collection values() : 获取所有的值组成的一个集合。
  • boolean containsValue(Object value) :

注意 没有add方法;

  • 使用put方法时,如果key不存在,将指定键值对添加到集合中。返回null
  • 使用put方法时,如果key存在,替换值,返回被替换之前的值。

遍历Map的方式

map.put("胡歌", "霍建华");
map.put("郭德纲", "于谦");
map.put("薛之谦", "大张伟");

for(String key : map.keySet())
    System.out.println(map.get(key));

二、Entry键值对对象概念??

  • Entry项概念:Key,Value一一对应的关系,Entry将键值对的对应关系封装成了对象
  • 可以通过Set entrySet()获得Entry集合。
  • 遍历的时候,将键值对作为一个封装的对象。包含的方法(省略public)
    • K getKey() :获取Entry对象中的键。
    • V getValue() :获取Entry对象中的值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

HashMap map = new HashMap<>();

map.put("胡歌", "霍建华");
map.put("郭德纲", "于谦");
map.put("薛之谦", "大张伟");

for(Map.Entry entry : map.entrySet()) {
    System.out.println("Key: " + entry.getKey());
    System.out.println("Value: " + entry.getValue());
}

// 等同于如下形式
Set> entrySet = map.entrySet();
for(Map.Entry entry : entrySet) {
    System.out.println(entry.getKey() + " : "  + entry.getValue());
}

三、HashMap存储自定义类型的键值对

注意: 如果使用自定义类作为键值对的Key,必须重写 equalshashCode 方法!以保证键值对唯一,(Java默认以地址为基准进行hash并设置Key)

import java.util.HashMap;
import java.util.Objects;

public class Student {
    private String name;
    private int age;

    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 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);
    }

    @Override
    public String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}'; }

    public static void main(String[] args) {
        HashMap map = new HashMap<>();

        map.put(new Student("王飞", 22), "重庆");
        map.put(new Student("王健", 23), "重庆");
        map.put(new Student("王飞", 22), "贵州");
        map.put(new Student("刘成", 23), "成都");

        for(Student student : map.keySet())
            System.out.println(student + " : " + map.get(student));
    }
}

四、LinkedHashMap

  • 链表+哈希表:存取有序,查找快

链表用于记录添加的顺序,也就是保存put进入的地址,而且在更改的时候会进行维护(顺序不变)。从而保证了有序!

HashMap map = new LinkedHashMap<>();
map.put("四川", "成都");
map.put("重庆", "重庆");
map.put("湖南", "长沙");

for(Map.Entry entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

System.out.println("=-=-=--=--=-=-=-=-=-==-");

// 如果修改的已经存在,顺序还是不会变
map.put("四川", "蓉城");
for(Map.Entry entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

你可能感兴趣的:(30.Map双列集合)