源无极

导航

 

   一 、

TreeMap中的元素默认按照keys的自然排序排列。

(对Integer来说,其自然排序就是数字的升序;对String来说,其自然排序就是按照字母表排序

 

案例一 

 @Test
    public void TreeMapTest1()  {
      Map<Integer, Integer> map = new TreeMap<>();
    map.put(3,8);
map.put(2,7);
map.put(1,9);
map.put(4,6);
 System.out.println("map= "+map); }

 

 

 

 

案例二

 @Test
    public void TreeMapTest2()  {
        Map<Integer, String> map = new TreeMap<>();
           map.put(3,"8");
map.put(2,"7");
map.put(1,"9");
map.put(4,"6");
 System.out.println("map= "+map); }

 

 

 

 

 

案例三

  @Test
    public void TreeMapTest3()  {
        Map<Integer, String> map = new TreeMap<>();
        map.put(3,"g");
        map.put(2,"b");
        map.put(1,"f");
        map.put(4,"k");
        System.out.println("map= "+map);
    }

 

 

 

案例四

 @Test
    public void TreeMapTest3()  {
        Map<String, Integer> map = new TreeMap<>();
        map.put("g",4);
        map.put("b",1);
        map.put("f",2);
        map.put("k",3);

        System.out.println("map= "+map);
    }

 

 

 案例五

 @Test
    public void TreeMapTest4()  {
        Map<String, String> map = new TreeMap<>();
        map.put("g","c");
        map.put("b","a");
        map.put("f","d");
        map.put("k","b");

        System.out.println("map= "+map);
    }

 

 

 

结论一:由以上知道,对Integer来说,其自然排序就是数字的升序  指的是针对key来说的。

结论二:同理,对String来说,其自然排序就是按照字母表排序) 指的也是key来说。

 

二、Api的使用

TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(1, "a");
treeMap.put(2, "b");
treeMap.put(3, "c");
treeMap.put(4, "d"); // treeMap: {1=a, 2=b, 3=c, 4=d}

treeMap.remove(4); // treeMap: {1=a, 2=b, 3=c}
int sizeOfTreeMap = treeMap.size(); // sizeOfTreeMap: 3

treeMap.replace(2, "e"); // treeMap: {1=a, 2=e, 3=c}

Map.Entry entry = treeMap.firstEntry(); // entry: 1 -> a
Integer key = treeMap.firstKey(); // key: 1
entry = treeMap.lastEntry(); // entry: 3 -> c
key = treeMap.lastKey(); // key: 3
String value = treeMap.get(3); // value: c

SortedMap sortedMap = treeMap.headMap(2); // sortedMap: {1=a} sortedMap = treeMap.subMap(1, 3); // sortedMap: {1=a, 2=e} Set setOfEntry = treeMap.entrySet(); // setOfEntry: [1=a, 2=e, 3=c] Collection<String> values = treeMap.values(); // values: [a, e, c] treeMap.forEach((integer, s) -> System.out.println(integer + "->" + s)); // output: // 1 -> a // 2 -> e // 3 -> c

 

 

三、多线程问题

案例一  线程不安全

 @Test
    public void TreeMapTest5() throws InterruptedException {
        Map<String, Integer> map = new TreeMap<>();
        //线程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("a100")){
                   map.replace("a100",888);
               }
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

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

 

 

 

 

案例二  线程安全

 @Test
    public void TreeMapTest5() throws InterruptedException {
        //Map<String, Integer> map = new TreeMap<>();
       Map<String, Integer> map = new ConcurrentSkipListMap<>();
        //线程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("a100")){
                   map.replace("a100",888);
               }
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

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

 

 

 

 

 

四、 常用方法

增添元素

  • V put(K key, V value):将指定映射放入该TreeMap中
  • V putAll(Map map):将指定map放入该TreeMap中

删除元素

  • void clear():清空TreeMap中的所有元素
  • V remove(Object key):从TreeMap中移除指定key对应的映射

修改元素

  • V replace(K key, V value):替换指定key对应的value值
  • boolean replace(K key, V oldValue, V newValue):当指定key的对应的value为指定值时,替换该值为新值
  •  

     

查找元素

  • boolean  containsKey(Object key):判断该TreeMap中是否包含指定key的映射
  • boolean  containsValue(Object value):判断该TreeMap中是否包含有关指定value的映射
  • Map.Entry<K, V> firstEntry()返回该TreeMap的第一个(最小的)映射
  • K firstKey():返回该TreeMap的第一个(最小的)映射的key
  • Map.Entry<K, V> lastEntry():返回该TreeMap的最后一个(最大的)映射
  • K lastKey():返回该TreeMap的最后一个(最大的)映射的key
  • v get(K key):返回指定key对应的value
  • SortedMap<K, V> headMap(K toKey):返回该TreeMap中严格小于指定key的映射集合
  • SortedMap<K, V> subMap(K fromKey, K toKey):返回该TreeMap中指定范围的映射集合(大于等于fromKey,小于toKey)

遍历接口

  • Set<Map<K, V>> entrySet():返回由该TreeMap中的所有映射组成的Set对象
  • void forEach(BiConsumer<? super K,? super V> action):对该TreeMap中的每一个映射执行指定操作
  • Collection<V> values()返回由该TreeMap中所有的values构成的集合

其他方法

  • Object clone():返回TreeMap实例的浅拷贝
  • Comparator<? super K> comparator():返回给该TreeMap的keys排序的comparator,若为自然排序则返回null
  • int size():返回该TreepMap中包含的映射的数量

补充:如何选择合适的Map

  • HashMap可实现快速存储和检索,但其缺点是其包含的元素是无序的,这导致它在存在大量迭代的情况下表现不佳。
  • LinkedHashMap保留了HashMap的优势,且其包含的元素是有序的。它在有大量迭代的情况下表现更好
  • TreeMap能便捷的实现对其内部元素的各种排序,但其一般性能比前两种map差。

LinkedHashMap映射减少了HashMap排序中的混乱,且不会导致TreeMap的性能损失。



 

posted on 2019-08-29 18:37  源无极  阅读(172)  评论(0编辑  收藏  举报