Summary of Map System of java_ Collection System (1)

1. Map overview

1.1 What is Map

A Map is an object that maps keys to values ​​( key-value ) . A map cannot contain duplicate keys ; each key can only map to at most one value. The Map interface provides three collection views, allowing you to view the contents of a map in the form of a key set (keySet()), a value set (values()), or a key-value mapping relationship set (entrySet()) (that is, get the key value correct content).

The mapping order is defined as the order in which the iterator returns its elements on the mapped collection view, that is , the Set collection of keys, values ​​and key-values ​​can be mapped, and the order of elements is determined by the obtained Set collection. Some map implementations explicitly guarantee their order, such as the TreeMap class; others do not, such as the HashMap class.

1.11, Map interface

Map<K,V>, which adds elements one pair at a time (aka key-value pairs). K is the key and V is the value. Whereas Collection adds one element at a time. The Map collection is also called a two-column collection, and the Collection collection is also called a single-column collection. In fact, what is stored in the Map collection is the key-value pair, and the uniqueness of the key (K) is guaranteed.

Commonly used subclasses of Map:

1. Hashtable: The internal structure is a hash table, which is synchronized. Null is not supported as key and value.

2. HashMap: The internal structure is a hash table, not synchronized, and supports null as a key and value.

3. TreeMap: The internal structure is a binary tree, not synchronized, and supports null as a key and value.

The commonly used methods of the Map interface are as follows:

1. Add

value put(key,value);//Returns the previous value associated with the key, or null if not

2. Delete

value remove(key);//Delete the key-value pair according to the specified key
void clear();//Clear this Map collection

3. Judgment

boolean  containsKey(key);
boolean  containsValue(value);
boolean isEmpty();//Determine whether it is empty

4. Get

value get(key);//Use the key to return the value, if there is no value the key returns null. Of course, you can determine whether the specified key (K) is included by returning null
int size();//Get the number of key-value pairs

1.12. How is the Map interface instantiated and how to traverse elements? ?

Here is an example of HashMap instantiation:

Map<Integer,String> map=new HashMap<Integer,String>();//Instantiate a HashMap object

Note: Question: How to get all the elements in the map? ? ?

The principle of taking out the elements in the map is as follows: use the keySet method to obtain the Set collection where all the keys in the map are located, and then obtain each key through the Set iterator. Then get the corresponding value for each key through the get() method of the map collection.

1.2 The difference between Map and Collection

  • 1.Map stores elements in the form of key-value pairs, the keys are unique, and the values ​​can be repeated.
  • 2.Collection stores a single-column element, the sub-interface Set element is unique, and the sub-interface List element can be repeated.
  • 3. The data structure value of the Map collection is valid for the key, regardless of the value, the data structure of the Collection collection is valid for the element

About Collection, you can poke here Collection instance analysis of java collection framework

2. Map inheritance system

The following lists the inheritance system of common Map collections and their characteristics

---Map 键唯一
    |------HashMap
    基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 此实现不是同步的。
        |------LinkedHashMap
    Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。此实现不是同步的
    |------WeakHashMap
    以弱键 实现的基于哈希表的 Map。在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除,null 值和 null 键都被支持。
    |------Hashtable
    此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。        Hashtable 是同步的 

    |------TreeMap
    基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 此实现不是同步的

3. Map generic interface

Map features: It consists of key-value key-value pairs, the key cannot be repeated, and the value can be repeated

It roughly includes the following functions:

  • Insert (put, putAll()), delete (remove())
  • 获取(entrySet()、get()、keySet()、size()、values())
  • 判断(containsKey()、containsValue()、equals()、isEmpty())、清除(clear())
  • Replace (replace(), replace(K key, V oldValue, V newValue) After jdk1.8, the following examples will talk about them)

  • void clear() 
              从此映射中移除所有映射关系(可选操作)。 
     boolean containsKey(Object key) 
              如果此映射包含指定键的映射关系,则返回 trueboolean containsValue(Object value) 
              如果此映射将一个或多个键映射到指定值,则返回 trueSet<Map.Entry<K,V>> entrySet() 
              返回此映射中包含的映射关系的 Set 视图。 
     boolean equals(Object o) 
              比较指定的对象与此映射是否相等。 
     V get(Object key) 
              返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 
     int hashCode() 
              返回此映射的哈希码值。 
     boolean isEmpty() 
              如果此映射未包含键-值映射关系,则返回 trueSet<K> keySet() 
              返回此映射中包含的键的 Set 视图。 
     V put(K key, V value) 
              将指定的值与此映射中的指定键关联(可选操作)。 
     void putAll(Map<? extends K,? extends V> m) 
              从指定映射中将所有映射关系复制到此映射中(可选操作)。 
     V remove(Object key) 
              如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 
     int size() 
              返回此映射中的键-值映射关系数。 
     Collection<V> values() 
              返回此映射中包含的值的 Collection 视图。
  • 3.1. Common ways of traversing the Map collection

    Method 1. Get the value according to the key (key -> value)

    1.获取所有键的集合
    2.遍历键的集合,获取到每一个键
    3.根据键找值
    

    Method 2. Get the key and value according to the key-value object ( entrySet -> key, value)

    1.获取所有键值对对象的集合
    2.遍历键值对对象的集合,获取到每一个键值对对象
    3.根据键值对对象找键和值
    
  • 3.11 Map usage example

    public class MapReview {
        public static void main(String[] args) {
            Map<String, String> map=new HashMap<String, String>();
            map.put("000", "qqq");
            map.put("003", "rrr");
            map.put("001", "www");
            map.put("002", "eee");
            map.put("004", "sss");
    
            // System.out.println(map);  // 直接打印输出键值对
    
            // 遍历1 : 通过键值对对象entrySet获取键与值
            Set<Entry<String, String>> entrySet = map.entrySet();
            for (Entry<String, String> entry : entrySet) {
                String key = entry.getKey();
                String value = entry.getValue();
                System.out.println("key="+key+" value="+value);
            }
            System.out.println("-------------------");
    
            // 遍历2 : 通过键keySet获取值
            Set<String> keySet = map.keySet(); // 得到键的集合
            for (String key : keySet) {
                String value = map.get(key);
                System.out.println("key="+key+" value="+value);
            }
            System.out.println("-------------------");
    
            // 获取Map值的集合
            Collection<String> values = map.values();
            System.out.println(values);
    
            // 判断是否存在键和值
            System.out.println("containsKey="+map.containsKey("001"));
            System.out.println("containsKey="+map.containsValue("eee"));
    
            // 向Map集合添加元素时,若键存在,则返回之前与键对应的值
            String put = map.put("000", "aaa");
            System.out.println("put="+put); // output: qqq
    
            //  default V replace(K key, V value)
            //  替换功能,将旧值替换成新值,并返回旧值(若有的话)
            String replace = map.replace("003", "666");
            System.out.println("replace="+replace);
            System.out.println(map);
    
            // default boolean replace(K key, V oldValue, V newValue
            // 只有当键key存在,并且oldValue与newValue相等时,旧的值才会被替换成新的值,并且返回true
            boolean success = map.replace("004", "sss", "lll"); 
            System.out.println("replace2="+success); // output : true
        }
    }
  • 3.2、 HashMap

    3.21. Features of HashMap

    ①键是哈希表结构,可以保证键的唯一性,
    ②当向已存在key的Map中添加元素时,会覆盖掉旧值,并将旧值返回。
    ③它允许使用 null 值和 null 键,但不保证映射的顺序,特别是它不保证该顺序恒久不变(即不会保证存储的顺序与输出的顺序恒久不变)。 
    ④此实现不是同步的。
    

    Note :

    For custom objects, you need to override their equals and hashCode methods to ensure the uniqueness of their keys

    3.22. Similarities and differences between HashMap and Hashtable

    除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同
    

    3.23. Example of use of HashMap

    public class HashMapReview {
        public static void main(String[] args) {
            test1();
            test2();
    
        }
    
        /**
         * 自定义类型做key,
         * 需重写其equals和hashCode方法才能保证其key的唯一性
         */
        private static void test2() {
            HashMap<Info, String> map=new HashMap<Info, String>();
            map.put(new Info(0, "aaa"),"0000");
            map.put(new Info(1, "bbb"),"1111");
            map.put(new Info(3, "ddd"),"3333");
            map.put(new Info(0, "aaa"),"4444");
            map.put(new Info(2, "ccc"),"2222");
            printMap(map);
            // output:
    //      key=Info [id=3, adress=ddd] value=3333
    //      key=Info [id=2, adress=ccc] value=2222
    //      key=Info [id=0, adress=aaa] value=0000
    //      key=Info [id=1, adress=bbb] value=1111
    //      key=Info [id=0, adress=aaa] value=4444  // 当Info没有重写equals和hashCode方法时,key出现重复元素
        }
    
        /**
         * String或基本数据类型的包装类做key,他们已重写了hashCode与equals方法
         * 键唯一,重复添加会替换旧值成新值
         */
        private static void test1() {
            HashMap<String, String> map=new HashMap<String, String>();
            map.put("aaa", "123");
            map.put("bbb", "789");
            map.put("aaa", "456");
            map.put("ccc", "321");
            System.out.println(map);
            // output:
    //      {aaa=456, ccc=321, bbb=789}
            // 重复的键不会重新插入,只会替换旧值成新值
        }
    
        private static void printMap(Map<Info, String> map) {
            Set<Entry<Info, String>> entrySet = map.entrySet();
            for (Entry<Info, String> entry : entrySet) {
                System.out.println("key="+entry.getKey()+" value="+entry.getValue());
            }
        }
    }
  • 3.24 A HashMap interview question

    The requirements are as follows:

     已知一个HashMap<Integer,Person>集合, Person有name(String)和age(int)属性。
     请写一个方法实现对HashMap的排序功能。该方法接收HashMap<Integer,Person>为形参,返回类型为HashMap<Integer,Person>,要求对HashMap中的Person的age升序进行排序。排序时key=value键值对不得拆散。
    • 1
    • 2

    analyze:

    HashMap本身是不保证元素的顺序不变的,要对其排序可使用LinkedHashMap,它是有序的并且还是HashMap的子类,我们可以使用它来完成排序的目的。最后返回它的实例即可满足要求 并且还符合多态的编程思想 
    

    sample code

    public class SortedHashMapDemo {
        public static void main(String[] args) {
            HashMap<Integer, Person> map = new LinkedHashMap<Integer, Person>();
            map.put(0, new Person("小明", 20));
            map.put(1, new Person("小二", 26));
            map.put(2, new Person("小四", 19));
            map.put(3, new Person("阿七", 33));
            map.put(4, new Person("十四", 25));
            map.put(4, new Person("小花", 19));
            System.out.println(map);
            HashMap<Integer, Person> sortedHashMap = SortedHashMap(map);
            System.out.println(sortedHashMap);
        }
    
        public static HashMap<Integer, Person> SortedHashMap(
                HashMap<Integer, Person> map) {
            // 获得键值对Set集合
            Set<Entry<Integer, Person>> entrySet = map.entrySet();
            // 将键值对Set集合转化为List以用Collections来排序
            List<Entry<Integer, Person>> list = new ArrayList<Map.Entry<Integer, Person>>(
                    entrySet);
            // 通过Collections来排序,添加比较器,比较年龄
            Collections.sort(list, new Comparator<Entry<Integer, Person>>() {
                @Override
                public int compare(Entry<Integer, Person> o1, Entry<Integer, Person> o2) {
                    int result = o2.getValue().age - o1.getValue().age;
                    result = result == 0 ? o2.hashCode() - o1.hashCode() : result;
                    return result;
                }
            });
    
            // 创建LinkedHashMap来存储排好序的List元素
            LinkedHashMap<Integer, Person> linkedHashMap = new LinkedHashMap<Integer, Person>();
            // 遍历List,将元素添加到linkedHashMap中
            for (Entry<Integer, Person> entry : list) {
                linkedHashMap.put(entry.getKey(), entry.getValue());
            }
    
            return linkedHashMap;
        }
    }
    
    class Person {
        String name;
        int age;
    
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    }

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326570317&siteId=291194637