Map集合

双列集合,与Collection集合不同(单列集合)。

Map<K, V>

K-此映射所维护的键的类型
V-映射值的类型
一个对象包括两个值(一个键,一个值)
值可以重复,键不能重复
image.png

特点:

1.Map是一个双列集合,一个元素包含两个值(一个key,一个value)
2.Map集合中的元素,key和value的数据类型可以相同,也可以不同。
3.Map集合中的元素,key不允许重复,value允许重复
4.Map集合中的元素,key和value是一一对应的

类HashMap<K,V>

HashMap<K, V> implements Map<K, V>
底层是一个哈希表结构,HashSet就是new的HashMap,但是只使用了K
不同步,多线程,速度快

子类 LinkedHashMap

LinkedHashMap<K, V> extends HashMap<K, V>

Map接口的哈希表和链表列表实现,可预知的迭代顺序。
特点:
1.底层:哈希表 + 链表(保证迭代的顺序)
2.有序集合

key也不允许重复

Hashtable类

底层是一个哈希表,双列集合
不允许存储null值(之前所学集合均可以存储),key与value都不能为空。
线程安全的集合,同步单线程,速度慢

被HashMap取代了,但是Hashtable的子类Properties集合(唯一和I/O流相结合的集合)依旧活跃

Map接口中常用方法

V put(K k, V value);
将指定的值与此映射中的指定键关联
返回值V:
存储的时候,key不重复,返回值null
key重复,用新的value替换map中重复的value,返回被替换的value

 Map<String, String> map = new HashMap<>();

String hh = map.put("lichen", "gbb");
System.out.println(map);
{lichen=gbb}

System.out.println("V1 = " + hh);
 // V1 = null


String hh2 = map.put("lichen", "gbb222");
System.out.println(map);
 // {lichen=gbb222}
 
System.out.println("v2 = " + hh2);
 // v2 = gbb
 

        map.put("000", "gbb");
        map.put("123", "gbb");
        map.put("222", "gbb");

        System.out.println(map);
 // {000=gbb, 123=gbb, 222=gbb}

V get(Object key);
返回指定键所映射的值,如果此映射不包含该键的映射关系,返回null

V remove(Object key);
如果存在一个键的映射关系,则将其从此映射中移除

        Map<String, Integer> map = new HashMap<>();
        map.put("123", 168);
        map.put("456", 178);
        map.put("789", 188);
        System.out.println(map);

        Integer v1 = map.remove("123");
        System.out.println(map);
        System.out.println(v1);
        
        // {123=168, 456=178, 789=188}
        // {456=178, 789=188}
        // 168

boolean containsKey(Object key);
如果此映射包含指定键的映射关系,返回true

        Map<String, Integer> map = new HashMap<>();
        map.put("123", 111);
        map.put("456", 222);
        map.put("789", 333);

        boolean b = map.containsKey("123");
        System.out.println(b);   //true
        boolean b1 = map.containsKey("1323");
        System.out.println(b1);  //false    

Set<K> keySet();
返回此映射中包含的键的Set视图
把Map集合中所有的key取出来,存到Set集合当中
应用:通过键找值的方式来遍历集合
image.png

        Map<String, Integer> map = new HashMap<>();

        map.put("123", 123);
        map.put("456", 456);
        map.put("789", 789);

        Set<String> set = map.keySet();

        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = it.next();
            Integer value = map.get(key);
            System.out.println("key = " + key
             + ", value = " + value);
        }
        /*
        key = 123, value = 123
        key = 456, value = 456
        key = 789, value = 789
        */

Set<Map.Entry<K, V>> entrySet();
返回此映射包含的映射关系的Set视图

Map中有一个内部接口Entry
作用:当Map集合一创建,就会在Map中创建一个Entry对象,用来记录键与值(键与值的映射关系) -->结婚证

遍历Set集合,获取Set集合中的每一个Entry对象
image.png
Entry对象中的方法:
用getKey()获得key
用getValue()获得value

        Map<String, Integer> map = new HashMap<>();
        map.put("123", 123);
        map.put("456", 456);
        map.put("789", 789);

        Set<Map.Entry<String, Integer>> set = map.entrySet();
        Iterator<Map.Entry<String, Integer>> it = set.iterator();

        while (it.hasNext()) {
            Map.Entry<String, Integer> next = it.next();
            String key = next.getKey();
            Integer value = next.getValue();
            System.out.println(key + " = " + value);
        }
        System.out.println("========");

        for (Map.Entry<String, Integer> entry : set) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + " = " + value);
        }
        /*
        123 = 123
        456 = 456
        789 = 789
        ========
        123 = 123
        456 = 456
        789 = 789
        */

HashMap存储自定义类型键值

String类重写了HashCode方法和equals方法,使得不会重复键


    private static void show01() {
        Map<String, Person> map = new HashMap<>();

        map.put("北京", new Person("123", 18));
        map.put("上海", new Person("456", 20));
        map.put("北京", new Person("789", 232));

        Set<String> set = map.keySet();

        for (String key : set) {
            Person value = map.get(key);
            System.out.println(key + "--->" + value);
        }
    }

key:Person类型
必须保证Person类型重写hashCode方法和equals方法,保证key唯一
value:String类型

private static void show02() {
        Map<Person, String> map = new HashMap<>();
        map.put(new Person("女王", 18), "英国");
        map.put(new Person("秦始皇", 39), "秦国");
        map.put(new Person("女王", 18), "美国");

        Set<Map.Entry<Person, String>> set = map.entrySet();
        for(Map.Entry<Person, String> entry : set) {
            Person key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "-->" + value);
        }
    }

未重写hashCode和equals:
Person{name='秦始皇', age=39}-->秦国
Person{name='女王', age=18}-->英国
Person{name='女王', age=18}-->美国
女王重复了但以及没有删除多余的

重写hashCode和equals:

Person{name='女王', age=18}-->美国
Person{name='秦始皇', age=39}-->秦国

遍历字符串,获取每个字符:(方法)!!!
1.String类的方法toCharArray,把字符串转换为一个字符串数组,遍历数组
2.String类的方法length() + charAt(索引)

JDK9对集合添加的优化

在集合中一次性添加多个元素
使用前提
当集合中的储存元素的个数已经确定,不再改变时使用

注意事项:
List、Set、Map中,含有一个静态工厂方法,不适用于接口的实现类
返回值是一个不能改变集合,(不能再使用add,put添加元素)
Set接口和Map接口在调用of方法时候,不能有重复的元素,否则会抛出异常

Set<String> st1 = Set.of("a", "b", "c");
List<String> str2 = List.of("a", "b", "c");
Map<String> str3 = Map.of("a", "b", "c");

waikiki
4 声望2 粉丝