美文网首页
集合(Map)

集合(Map)

作者: 冯宏志 | 来源:发表于2020-12-21 19:59 被阅读0次

    Map:

    • 双列数据,存储key-value对的数据 ----->类似于函数y=f(x)
    • Map结构的理解:
      1、Map中的key:无序的,不可重复的,使用Set存储所有的key ----->key所在的类要重写equals()和hashCode()(以HashMap为例)
      2、Map中的value:无序的、可重复的,使用Collection存储所有的value ----->value所在的类要重写equals()
      3、一个键值对:key-value构成了一个Entry对象
      4、Map中的entry:无序的、不可重复的,使用Set存储所有的entry
    • Map常用方法:添加、删除、修改、查询、长度、遍历(注意:没有插入)
    import org.junit.Test;
    
    import java.util.*;
    
    public class MapTest {
        @Test
        public void test1(){
            Map map = new HashMap();
            //添加
            map.put("AA",123);
            map.put(123,123);
            map.put("BB",456);
            //修改:覆盖原数据
            map.put("AA",456);
            System.out.println(map);//{AA=456, BB=456, 123=123}
    
            Map map1 = new HashMap();
            map1.put("CC",1);
            map1.put("DD",2);
            //putAll(Map map1)
            map.putAll(map1);
            System.out.println(map);//{AA=456, BB=456, CC=1, DD=2, 123=123}
    
            //remove()
            Object value = map.remove("CC");
            System.out.println(value);//1:"CC"对应的值
            System.out.println(map);//{AA=456, BB=456, DD=2, 123=123}
    
            //clear():把value清空
            map.clear();
            System.out.println(map.size());//0
            System.out.println(map);//{}
        }
    
        @Test
        public void test2(){
            Map map = new HashMap();
            map.put("AA",123);
            map.put(123,123);
            map.put("BB",456);
    
            //Object get(Object key)
            System.out.println( map.get("AA"));//123
    
            //boolean containsKey(Object key)
            boolean isExist = map.containsKey("BB");
            System.out.println(isExist);//true
    
            //boolean containsValue(Object value)
            boolean isExist1 = map.containsValue(123);//key为:"AA",123,所对应的value都为123,找到一个就不再找下去
            System.out.println(isExist1);//true
    
            //isEmpty()
            map.clear();
            System.out.println(map.isEmpty());//true
    
            //equals
            Map map1 = new HashMap();
            map1.put("A",1);
            Map map2 = new HashMap();
            map2.put("A",1);
    
            System.out.println(map1.equals(map2));//true
        }
    
        @Test
        public void test3() {
            Map map = new HashMap();
            map.put("AA",123);
            map.put(123,123);
            map.put("BB",456);
    
            //遍历所有key集:keySet()
            Set set = map.keySet();
            Iterator iterator = set.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next() );//"AA","BB",123
            }
    
            //遍历所有的value:values()
            Collection values = map.values();
            Iterator iterator1 = values.iterator();
            while (iterator1.hasNext()){
                System.out.println(iterator1.next());//123,456,123
            }
    
            //遍历所有key-value:
            // 方式一:entrySet()
            Set entrySet = map.entrySet();//entrySet是一个Set类型,其中存放的数据类型是Entry
            Iterator iterator2 = entrySet.iterator();
            while (iterator2.hasNext()){
                Object obj = iterator2.next();
                Map.Entry entry = (Map.Entry) obj;
                System.out.println(entry.getKey());//"AA","BB",123
            }
    
            //方式二:使用getKey()得到key,再调用get
            Set keySet = map.keySet();
            Iterator iterator3 = keySet.iterator();
            while (iterator3.hasNext()){
                Object key = iterator3.next();
                Object value = map.get(key);
                System.out.println(value);//123,456,123
            }
        }
    
    }
    
    

    HashMap:

    • 作为Map的主要实现类,线程不安全,效率高,可以存储null的key和value
    • HashMap的底层原理(以jdk7为例)
      在实例化以后,底层创建了长度是16的一维数组Entry[] table
      map.put(key1,value1)//在此之前可能已经执行过多次put
      首先,调动key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
      如果此位置上的数据为空,此时的key1-value1添加成功
      如果此位置上的数据不为空(意味着此位置上存在一个或多个数据),比较key1和已经存在的一个或多个数据的哈希值:
      ----如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功
      ----如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals()方法,比较:
      --------如果equals()返回false:此时key1-value1添加成功
      --------如果equals()返回true:使用value1替换value2的值

    注:扩容时,当超出临界值(且要存放的位置不是null)。 扩容为原来的2倍

    • jdk8相较于jdk7在底层实现方面的不同
      1、new HashMap():底层没有创建一个长度16的数组
      2、jdk8底层的数组是:Node[],而非Entry[]
      3、首次调用put()方法时,底层创建长度16的数据
      4、jdk7底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树。当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储。
      DEFAULT_INITIAL_CAPACITYHashMap的默认容量:16
      DEFAULT_LOAD_FACTORHashMap的默认加载因子:0.75
      threshold扩容的临界值 = 容量填充因子:160.75=>12
      TREEIFY_THRESHOLDBucket中链表长度大于该默认值,转化为红黑树:8
      MIN_TREEIFY_CAPACITYNode被树化时最小的hash表容量:64
    LinkedHashMap(HashMap的子类):
    • 保证在遍历Map元素时,可以按照添加的顺序实现遍历。原因:在HashMap的基础上,添加了一对指针,指向前一个和后一个元素(双向链表)。
    • 对于频繁的遍历操作,此类执行效率高于HashMap
    • 底层:在Entry里面加了befor,after引用,相当于构成一个双向链表

    TreeMap:

    • 保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序,底层使用红黑树
    • 向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
    • 因为要按照key进行排序:自然排序,定制排序

    HashTable:

    • 作为古老的实现类,线程安全,效率低,不可以存储null 的key和value
    Properties:
    • 常用来处理配置文件。key和value都是String类型
    import java.io.FileInputStream;
    import java.util.Properties;
    
    public class PropertiesTest {
        public static void main(String[] args) throws Exception{
            //Properties:常用来处理配置文件。key和value都是String类型
            Properties prop = new Properties();
            FileInputStream fis = new FileInputStream("set.properties");
            prop.load(fis);//加载流对应文件
    
            String name = prop.getProperty("name");
            String age = prop.getProperty("age");
            System.out.println(name);//fhz
            System.out.println(age);//20
        }
    }
    
    

    相关文章

      网友评论

          本文标题:集合(Map)

          本文链接:https://www.haomeiwen.com/subject/dgwvwktx.html