源无极

导航

 

       一、使用常识

    HashMap是一中比较常用的,也比较好用的集合,但是HashMap有一个顺序的问题,就是在对HashMap进行迭代访问时,

添加的顺序和访问的顺序可能就不一样的,这个时候我们可以选择LinkedHashMap,
LinkedHashMap继承了HashMap,所以拥有和HashMap一样的功能;而且在此基础上有增加了一个双向链表来实现元素迭代的顺序,但是肯定会增加时间和空间的消耗,
LinkedHashMap和HashMap一样,也是非线程安全

我们还是先来看一个LinkedHashMap的实例,操作数据的方法和HasMap是一样的,代码如下:

 

案例一  基本使用

@Test
    public void LinkHashMapTest1()  {
      Map<String, Object> map = new LinkedHashMap<>();
      map.put("name","洛少");
      map.put("age",18);
      map.put("adress","斗破大陆");
      map.put(null,null);
      map.put(null,1);
      map.put("test",null);
      System.out.println("map= "+map);
    }

 

 

 结论

LinkedHashMap的输入顺序和输出顺序是一致的。
LinkedHashMap允许Key和Value都可以null
LinkedHashMap中添加元素时,如果Key重复,则后添加的会覆盖前面已经存在的值

 

分析源码得出:从以上可以判断LinkedHashMap实现就是 HashMap+LinkedList 的实现方式

 用HashMap维护数据结构,用LinkList的方式维护数据插入顺序

 

二、多线程分析:

案例一、线程不安全

 @Test
    public void LinkHashMapTest2() throws InterruptedException {
        Map<String, Object> map = new LinkedHashMap<>();

        //线程T-1
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 1; i < 500; i++) {
                map.put("a" + i, i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-1").start();
        //线程T-2
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 500; i <= 1000; i++) {
                map.put("a" + i, i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-2").start();

        //线程T-3
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 500; i <= 1000; i++) {
                if (map.containsKey("a120")) {
                    map.put("a120", 888);
                }
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-3").start();
        Thread.sleep(1000);
        System.out.println("a120= "+map.get("a120"));
        System.out.println("大小:" + map.size());
    }

 

 

 

案例二: 线程安全

如果必须使用 LinkedHashMap 且要线程安全

@Test
    public void LinkHashMapTest2() throws InterruptedException {
        //Map<String, Object> map = new LinkedHashMap<>();
        Map<String, Object> map = Collections.synchronizedMap(new LinkedHashMap<>());
        //线程T-1
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 1; i < 500; i++) {
                map.put("a" + i, i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-1").start();
        //线程T-2
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 500; i <= 1000; i++) {
                map.put("a" + i, i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-2").start();

        //线程T-3
        new Thread(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());

            for (int i = 500; i <= 1000; i++) {
                if (map.containsKey("a120")) {
                    map.put("a120", 888);
                }
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "T-3").start();
        Thread.sleep(1000);
        System.out.println("a120= "+map.get("a120"));
        System.out.println("大小:" + map.size());
    }

 

 

 

 

 

 

补充:

图解LinkedHashMap原理

 

posted on 2019-08-29 21:13  源无极  阅读(1090)  评论(0编辑  收藏  举报