天天看点

Java集合框架系列——TreeMap

直通车:Java集合框架系列目录

  1. 基本概念
  2. 继承关系
  3. 结构特点
  4. 常用API
  5. 遍历方式
  6. 代码示例

#1.基本概念

TreeMap:一种键值有序排列的映射表。

#2.继承关系

Java集合框架系列——TreeMap

TreeMap是一个继承于

AbstractMap

的散列表,它存储的内容是键值对(key/value)映射。

TreeMap 实现了

NavigableMap

接口,意味着它支持一系列的导航方法。比如返回有序的

key

集合。

TreeMap实现了

Cloneable

接口,即覆盖了函数

clone()

,能被克隆。

TreeMap实现

java.io.Serializable

接口,意即TreeMap支持序列化,能通过序列化传输。

public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable {}
           

#3.结构特点

  • 基于红黑树实现

    红黑树又称红-黑二叉树,它首先是一棵二叉树,它具备二叉树所有的特性。同时红黑树亦是一颗自平衡的排序二叉树。

  • 默认按升序排序

    如果需要按其他顺序排列,需要定义一个比较器类,实现

    Comparator

    接口,重写

    compare

    方法。
  • 不允许null键,允许null值

    可以通过覆写

    compare

    方法(令元素为

    null

    时返回非0值)来允许

    TreeMap

    添加null键。但这样做的话,在用

    get(null)

    时会返回

    null

TreeMap<String, Integer> ts = new TreeMap<>(new Comparator<String>() {
            public int compare(String s1, String s2) {      // 这里明确s1是要拿进来存的数据 s2是已经存进来的数据
                if (s1 == null) {
                    return 1;
                }
                else {
                    return s2.charAt(0) - s1.charAt(0);
                }
            }
        });
        ts.put(null, 3);
        System.out.println(ts.get(null));//输出null
           

不覆写

compare

的缺省情况下,

get(null)

会返回

java.lang.NullPointerException

空指针异常。

  • 不允许一键多值

    可以通过覆写

    compare

    方法(令元素相等时返回非0值)来允许

    TreeMap

    的某个键

    Key

    添加多个值。但这样做的话,在用

    get

    方法获取该键的

    Value

    时会返回

    null

Map<Integer, String> map = new TreeMap<>(new Comparator<Integer>() {

            public int compare(Integer i1, Integer i2) {
                // TODO Auto-generated method stub
                int num = i1 - i2;
                return num == 0 ? 1 : num;
            }
        });

        map.put(1, "一");
        map.put(2, "二");
        map.put(3, "三");
        map.put(1, "四");

        System.out.println(map.get(1));//输出null
           

不覆写

compare

的缺省情况下,如果有两次

put

操作传入的键相同,则其

Value

值以最后一次的为准。

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

        map.put(1, "一");
        map.put(2, "二");
        map.put(3, "三");
        map.put(1, "四");

        System.out.println(map.get(1));//输出 四
    }
           
  • 不是线程安全的

    可以用

    Collections

    synchronizedSortedMap

    方法使

    TreeMap

    具有线程安全的能力,或者使用

    ConcurrentSkipListMap

#4.常用API

API 含义
clear() 从 Map 中删除所有映射
remove(Object key) 从 Map 中删除键和关联的值
put(Object key, Object value) 将指定值与指定键相关联
putAll(Map t) 将指定 Map 中的所有映射复制到此 map
entrySet() 返回 Map 中所包含映射的 Set 视图。Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问后者的键元素和值元素
keySet() 返回 Map 中所包含键的 Set 视图。删除 Set 中的元素还将删除 Map 中相应的映射(键和值)
values() 返回 map 中所包含值的 Collection 视图。删除 Collection 中的元素还将删除 Map 中相应的映射(键和值)
get(Object key) 返回与指定键关联的值
containsKey(Object key) 如果 Map 包含指定键的映射,则返回 true
containsValue(Object value) 如果此 Map 将一个或多个键映射到指定值,则返回 true
isEmpty() 如果 Map 不包含键-值映射,则返回 true
size() 返回 Map 中的键-值映射的数目

#5.遍历方式

1.遍历TreeMap的键值对

第一步:根据entrySet()获取TreeMap的“键值对”的Set集合。

第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象
// map中的key是String类型,value是Integer类型
Integer integ = null;
Iterator iter = map.entrySet().iterator();
while(iter.hasNext()) {
    Map.Entry entry = (Map.Entry)iter.next();
    // 获取key
    key = (String)entry.getKey();
        // 获取value
    integ = (Integer)entry.getValue();
}
           

2.遍历TreeMap的键

第一步:根据keySet()获取TreeMap的“键”的Set集合。

第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象
// map中的key是String类型,value是Integer类型
String key = null;
Integer integ = null;
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
        // 获取key
    key = (String)iter.next();
        // 根据key,获取value
    integ = (Integer)map.get(key);
}
           

3.遍历TreeMap的值

第一步:根据value()获取TreeMap的“值”的集合。

第二步:通过Iterator迭代器遍历“第一步”得到的集合。

// 假设map是TreeMap对象
// map中的key是String类型,value是Integer类型
Integer value = null;
Collection c = map.values();
Iterator iter= c.iterator();
while (iter.hasNext()) {
    value = (Integer)iter.next();
}
           

#6.代码示例

import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

public class TreeMapTest {
    public static void main(String[] args) {
        TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
        TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();
        tMap.put("five", 5);
        tMap.put("six", 6);
        treeMap.put("one", 1);
        treeMap.put("two", 2);
        treeMap.put("three", 3);
        treeMap.put("four", 4);
        //返回treemap中元素的个数
        int size = treeMap.size();
        System.out.println("treemap中元素的个数为 : " + size);
        //如果treemap包含了一个指定key的映射关系,则返回true,否则返回false
        boolean t = treeMap.containsKey("one");
        System.out.println("treemap中包含了key=one的映射关系 :" + t);
        //如果在treemap中存在一个或者多个key映射了这个value,那么就返回true,否则返回false
        boolean tt = treeMap.containsValue(1);
        System.out.println("treemap中包含了value=1的映射:" + tt);
        //返回treemap中的key所映射的value
        Integer value = treeMap.get("two");
        System.out.println("key=two所映射的value : " + value);
        //返回当前映射中的第一个(最低)键
        String first = treeMap.firstKey();
        System.out.println(first);
        //返回当前映射中的最后一个(最高)键
        String last = treeMap.lastKey();
        System.out.println(last);
        //循环遍历treemap的key
        for(String key:treeMap.keySet()){
            System.out.print( key +"    ");
        }
        System.out.println();
        //把tmap全部添加到treemap集合中
        treeMap.putAll(tMap);
        System.out.println("添加以后的treemap大小是   : " + treeMap.size());
        //移除treemap中指定key所映射的关系
        treeMap.remove("one");
        //清除treemap中的所有映射关系
        //treeMap.clear();
        //返回一个对treemap进行浅克隆的实例,其中key和value本身是不会被克隆的,返回值类型是Object类型
        treeMap.clone();
        //返回treemap中的第一个键值对映射关系,等号左边是key,右边是value
        Entry<String, Integer> firstEntry =  treeMap.firstEntry();
        System.out.println("第一个键值对是 : " + firstEntry);
        //返回treemap中的最后一个键值对映射关系,等号左边是key,右边是value
        Entry<String, Integer> lastEntry = treeMap.lastEntry();
        System.out.println("最后一个键值对是 :" +lastEntry);
        //返回treemap中的第一个键值对映射关系,等号左边是key,右边是value
        Entry<String, Integer> pollFirst =  treeMap.pollFirstEntry();
        System.out.println("第一个键值对是 : " + pollFirst);
        //返回treemap中的最后一个键值对映射关系,等号左边是key,右边是value
        Entry<String, Integer> pollLast = treeMap.pollLastEntry();
        System.out.println("最后一个键值对是 :" + pollLast);
        //返回treemap中的key完全小于指定key的最大一个键值对映射关系,等号左边是key,右边是value,如果不存在则返回null
        Entry<String, Integer> lowerEntry =  treeMap.lowerEntry("three");
        System.out.println("完全小于指定key的最大一个键值对映射关系是 : " + lowerEntry);
        //返回treemap中的key完全大于指定key的最小一个键值对映射关系,等号左边是key,右边是value,如果不存在则返回null
        Entry<String, Integer> higherEntry = treeMap.higherEntry("three");
        System.out.println("完全大于指定key的最小一个键值对映射关系 :" + higherEntry);
        //返回完全小于指定key的最大key,如果这样的key不存在返回null
        String key = treeMap.lowerKey("two");
        System.out.println("完全小于指定key的最大key : " + key);
        //返回完全大于指定key的最小key,如果这样的key不存在返回null
        String minKey = treeMap.higherKey("three");
        System.out.println("完全大于指定key的最小key: " + minKey);
        //返回一个小于或者等于指定key的最大的映射关系,如果不存在则返回null
        Entry<String, Integer> floorEntry = treeMap.floorEntry("two");
        System.out.println("小于或者等于指定key的最大的映射关系: " + floorEntry);
        //返回一个小于或者等于指定key的最大的key,如果不存在则返回null
        String floorKey = treeMap.floorKey("three");
        System.out.println("小于或者等于指定key的最大的key: " + floorKey);
        //返回一个大于或者等于指定key的最小的映射关系,如果不存在则返回null
        Entry<String, Integer> ceilEntry = treeMap.ceilingEntry("two");
        System.out.println("大于或者等于指定key的最小的映射关系: " + ceilEntry);
        //返回一个大于或者等于指定key的最小的key,如果不存在则返回null
        String ceilKey = treeMap.ceilingKey("three");
        System.out.println("大于或者等于指定key的最小的key : " + ceilKey);
        //返回treemap中的所有key
        Set<String> keSet = treeMap.keySet();
        for(String k:keSet){
            System.out.print(k + "  ");
        }
        System.out.println();
        //返回该映射中包含的键的NavigableSet视图
        NavigableSet<String> n = treeMap.navigableKeySet();
        for(String k:n){
            System.out.print(k + "  ");
        }
        System.out.println();
        //返回该映射中包含的键的NavigableSet视图的逆序
        NavigableSet<String> m = treeMap.descendingKeySet();
        for(String k:m){
            System.out.print(k + "  ");
        }
        System.out.println();
        //返回treemap中的所有value
        Collection<Integer> integers = treeMap.values();
        for(Integer num:integers){
            System.out.print(num +"     ");
        }
        System.out.println();
        //返回treemap里面的所有映射关系,等号左边是key,等号的右边是value
        Set<Entry<String, Integer>> set = treeMap.entrySet();
        for (Entry<String, Integer> entry : set) {
            System.out.print( entry + "**");
        }
        System.out.println();
        //返回该映射中包含的映射的反向顺序视图
        NavigableMap<String, Integer>  sMap = treeMap.descendingMap();
        System.out.println(sMap);
        //返回集合中包含开始key,不包含结束key的所有映射关系,其中开始key一定小于结束key
        SortedMap<String, Integer>  sort = treeMap.subMap("six", "three");
        System.out.println("集合中包含开始key,不包含结束key的所有映射关系 : " + sort);
        //返回集合中完全小于指定key的所有映射关系
        SortedMap<String, Integer>  sort1 = treeMap.headMap("three");
        System.out.println("完全小于指定key的所有映射关系: " + sort1);
        //返回集合中完全大于于指定key的所有映射关系
        SortedMap<String, Integer>  sort2 = treeMap.tailMap("three");
        System.out.println("完全大于于指定key的所有映射关系 : " + sort2);
    }
}
           

如有谬误或不完善之处,恳请斧正!

继续阅读