Java容器_Map基本使用(4)

Map
Map

HashMap

基于哈希表,允许 key 和 value 为 null,不保存元素的插入顺序

put、remove、containsKey、containsValue、isEmpty、clear、size 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class Test {
  public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<>();
    //如果之前的键有值,put方法将返回被覆盖的值
    map.put("张三", 20);
    Integer i1 = map.put("张三", 21);
    System.out.println(i1); //被覆盖为21,返回之前的20
    map.put("李四", 22);
    System.out.println(map); //{李四=22, 张三=21}
    //remove返回被删除key对应的value
    Integer i2 = map.remove("张三");
    System.out.println(i2); //21
    System.out.println(map); //{李四=22}
    System.out.println(map.containsKey("李四")); //true
    System.out.println(map.containsValue(22)); //true
    System.out.println(map.isEmpty()); //false
    System.out.println(map.size()); //1
    map.clear();
    System.out.println(map); //{}
  }
}

get、keySet、values 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Test {
  public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<>();
    map.put("张三", 23);
    map.put("李四", 24);
    map.put("王五", 25);
    //根据key获取value
    System.out.println(map.get("张三")); //23
    //获取所有键的set
    Set<String> keySet = map.keySet();
    //Map没有迭代器,需要先获取所有键的set,再迭代
    Iterator<String> it = keySet.iterator();
    while (it.hasNext()) {
      String key = it.next();
      System.out.println(key + ":" + map.get(key));
    }
    //foreach的方式
    for (String key : keySet) {
      System.out.println(key + ":" + map.get(key));
    }
    //可以通过values直接遍历value值,但不能获取到对应key
    for (Integer v : map.values()) {
      System.out.println(v);
    }
  }
}

HashMap 嵌套

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
  public static void main(String[] args) {
    HashMap<String, Integer> cart1 = new HashMap<>();
    cart1.put("手机1", 1999);
    cart1.put("电脑1", 4999);
    HashMap<String, Integer> cart2 = new HashMap<>();
    cart2.put("手机2", 2999);
    cart2.put("电脑2", 7999);
    HashMap<String, HashMap<String, Integer>> order = new HashMap<>();
    order.put("0001", cart1);
    order.put("0002", cart2);
    for (String orderNum : order.keySet()) {
      HashMap<String, Integer> cart = order.get(orderNum);
      for (String product : cart.keySet()) {
        Integer price = cart.get(product);
        System.out.println(orderNum + ":" + product + ":" + price);
      }
    }
    //0002:电脑2:7999
    //0002:手机2:2999
    //0001:电脑1:4999
    //0001:手机1:1999
  }
}

与 Set 同理(Set 基于 HashMap),对于自定义类型的键 key,需要重写 hashCode、equals 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Test {
  public static void main(String[] args) {
    HashMap<Student, Integer> map = new HashMap<>();
    map.put(new Student("张三"), 20);
    map.put(new Student("张三"), 20);
    map.put(new Student("李四"), 21);
    //重写hashCode和equals方法前结果为{张三=20, 李四=21, 张三=20}
    System.out.println(map); //{李四=21, 张三=20}
  }
}
class Student {
  public String name;
  Student(String name) {
    this.name = name;
  }
  @Override
  public String toString() {
    return name;
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student s = (Student) o;
    return name.equals((s.name));
  }
  @Override
  public int hashCode() {
    return name.hashCode();
  }
}

Map.Entry

Map.Entry 是 Map 的一个内部接口,定义为 Entry<K,V> ,表示 Map 中的一个 key value 对

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Test {
  public static void main(String[] args) {
    Map<String, Integer> map = new HashMap<>();
    map.put("张三", 23);
    map.put("李四", 24);
    map.put("王五", 25);
    //Map.Entry是Map的内部接口
    //将key和value封装为Entry对象并存储在Set集合中
    Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
    //获取Entry对象的迭代器
    Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
    while (it.hasNext()) {
      Map.Entry<String, Integer> e = it.next();
      String key = e.getKey();
      Integer value = e.getValue();
      System.out.println(key + value); 
    }
    //foreach的方式
    for (Map.Entry<String, Integer> e : entrySet) {
      System.out.println(e.getKey() + e.getValue());
    }
    //李四24 张三23 王五25
  }
}

LinkedHashMap

LinkedHashMap 是 HashMap 的子类,其 Entry 被链入一个双向链表,以此来保存元素的插入顺序,LinkedHashMap 还支持 LRU 算法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class Test {
  public static void main(String[] args) {
    LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
    map.put("张三", 23);
    map.put("李四", 24);
    map.put("王五", 25);
    //LinkedHashMap 底层链表实现存取有序
    System.out.println(map); //{张三=23, 李四=24, 王五=25}
  }
}

TreeMap

基于红黑树,默认根据键 Key 的自然顺序排序,或根据传入的 Comparator 比较器进行排序,containsKey、get、put 和 remove 方法的时间复杂度都是 O(logn)

对自定义类型的键 key 进行排序,实现 Comparable 接口的方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Test {
  public static void main(String[] args) {
    TreeMap<Student, Integer> map = new TreeMap<>();
    map.put(new Student("李四四四四"), 21);
    map.put(new Student("张三三三"), 20);
    map.put(new Student("王五五五五五"), 22);
    System.out.println(map);
    //{张三三三=20, 李四四四四=21, 王五五五五五=22}
  }
}
class Student implements Comparable<Student> {
  public String name;
  Student(String name) {
    this.name = name;
  }
  @Override
  public String toString() {
    return name;
  }
  @Override
  public int compareTo(Student o) {
    return name.length() - o.name.length();
  }
}

传入 Comparator 比较器的方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Test {
  public static void main(String[] args) {
    TreeMap<Student, Integer> map = new TreeMap<>(new Comparator<Student>() {
      @Override
      public int compare(Student o1, Student o2) {
        return o1.name.length() - o2.name.length();
      }
    });
    map.put(new Student("李四四四四"), 21);
    map.put(new Student("张三三三"), 20);
    map.put(new Student("王五五五五五"), 22);
    System.out.println(map);
    //{张三三三=20, 李四四四四=21, 王五五五五五=22}
  }
}
class Student {
  public String name;
  Student(String name) {
    this.name = name;
  }
  @Override
  public String toString() {
    return name;
  }
}

以上内容是玉山整理的笔记,如有错误还请指出