Java集合框架系列——TreeMap

本文详细介绍了Java集合框架中的TreeMap,包括其基本概念、继承关系、结构特点,如基于红黑树实现,有序键值对等。此外,还探讨了TreeMap的常用API和多种遍历方法,以及它在多线程安全性上的不足。最后,提供了代码示例以加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

#1.基本概念
TreeMap:一种键值有序排列的映射表。

#2.继承关系
这里写图片描述

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));//输出 四
    }
  • 不是线程安全的
    可以用CollectionssynchronizedSortedMap方法使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);
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值