TreeMap集合基本介绍和源码剖析

TreeMap集合

基本介绍:

当我们使用无参构造器,创建TreeMap时,仍然是无序的

当我们需要按照某种方式进行排序时,需要使用TreeMap提供的一个构造器,可以传入一个比较器【匿名内部类】并指定排序规则

继承关系和构造器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CTGb9qus-1647575568234)(E:\Typora笔记\java笔记\img\image-20220318114655072.png)]

构造器:

Constructor and Description
TreeMap() 使用其键的自然排序构造一个新的空树状图。
TreeMap(Comparator<? super K> comparator) 构造一个新的,空的树图,按照给定的比较器排序。
TreeMap(Map<? extends K,? extends V> m) 构造一个新的树状图,其中包含与给定地图相同的映射,根据其键的 自然顺序进行排序
TreeMap(SortedMap<K,? extends V> m) 构造一个包含相同映射并使用与指定排序映射相同顺序的新树映射。

方法摘要

Modifier and TypeMethod and Description
Map.Entry<K,V>ceilingEntry(K key) 返回与大于或等于给定键的最小键相关联的键值映射,如果没有此键,则 null
KceilingKey(K key) 返回大于或等于给定键的 null键,如果没有此键,则返回 null
voidclear() 从这张地图中删除所有的映射。
Objectclone() 返回此 TreeMap实例的浅拷贝。
Comparator<? super K>comparator() 返回用于订购此地图中的键的比较器,或null如果此地图使用其键的natural ordering
booleancontainsKey(Object key) 如果此映射包含指定键的映射,则返回 true
booleancontainsValue(Object value) 如果此地图将一个或多个键映射到指定值,则返回 true
NavigableSet<K>descendingKeySet() 返回此地图中包含的键的相反顺序NavigableSet
NavigableMap<K,V>descendingMap() 返回此映射中包含的映射的反向排序视图。
Set<Map.Entry<K,V>>entrySet() 返回此地图中包含的映射的Set视图。
Map.Entry<K,V>firstEntry() 返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null
KfirstKey() 返回此地图中当前的第一个(最低)键。
Map.Entry<K,V>floorEntry(K key) 返回与小于或等于给定键的最大键相关联的键值映射,如果没有此键,则 null
KfloorKey(K key) 返回小于或等于给定键的最大键,如果没有这样的键,则返回 null
voidforEach(BiConsumer<? super K,? super V> action) 对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。
Vget(Object key) 返回到指定键所映射的值,或 null如果此映射包含该键的映射。
SortedMap<K,V>headMap(K toKey) 返回此地图部分的视图,其密钥严格小于 toKey
NavigableMap<K,V>headMap(K toKey, boolean inclusive) 返回此地图部分的视图,其键值小于(或等于,如果 inclusive为真) toKey
Map.Entry<K,V>higherEntry(K key) 返回与最小密钥相关联的密钥值映射严格大于给定密钥,如果没有这样的密钥则 null
KhigherKey(K key) 返回严格大于给定键的最小键,如果没有这样的键,则返回 null
Set<K>keySet() 返回此地图中包含的键的Set视图。
Map.Entry<K,V>lastEntry() 返回与该地图中最大关键字关联的键值映射,如果地图为空,则返回 null
KlastKey() 返回当前在此地图中的最后(最高)键。
Map.Entry<K,V>lowerEntry(K key) 返回与最大密钥相关联的密钥值映射严格小于给定密钥,如果没有这样的密钥,则 null
KlowerKey(K key) 返回严格小于给定键的最大键,如果没有这样的键,则返回 null
NavigableSet<K>navigableKeySet() 返回此地图中包含的键的NavigableSet视图。
Map.Entry<K,V>pollFirstEntry() 删除并返回与该地图中的最小键相关联的键值映射,如果地图为空,则返回 null
Map.Entry<K,V>pollLastEntry() 删除并返回与该地图中最大密钥相关联的键值映射,如果地图为空,则返回 null
Vput(K key, V value) 将指定的值与此映射中的指定键相关联。
voidputAll(Map<? extends K,? extends V> map) 将指定地图的所有映射复制到此地图。
Vremove(Object key) 从此TreeMap中删除此键的映射(如果存在)。
Vreplace(K key, V value) 只有当目标映射到某个值时,才能替换指定键的条目。
booleanreplace(K key, V oldValue, V newValue) 仅当当前映射到指定的值时,才能替换指定键的条目。
voidreplaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
intsize() 返回此地图中键值映射的数量。
NavigableMap<K,V>subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) 返回此地图部分的视图,其关键范围为 fromKeytoKey
SortedMap<K,V>subMap(K fromKey, K toKey) 返回此地图部分的视图,其关键字范围从 fromKey (含)到 toKey ,独占。
SortedMap<K,V>tailMap(K fromKey) 返回此地图部分的视图,其键大于等于 fromKey
NavigableMap<K,V>tailMap(K fromKey, boolean inclusive) 返回此地图部分的视图,其键大于(或等于,如果 inclusive为真) fromKey
Collection<V>values() 返回此地图中包含的值的Collection视图。

TreeMap源码剖析

package collection_.collectionP.map_;

import java.util.Comparator;
import java.util.TreeMap;

/**
 * @author: 海康
 * @version: 1.0
 */
public class TreeMap_ {
    public static void main(String[] args) {
        // 在使用无参构造器时,排序是无序的
        // 使用无参构造器返回值:{jack=杰克, kristina=克瑞斯提诺, smith=斯密斯, tom=汤姆}
        TreeMap treeMap = new TreeMap();
//        TreeMap treeMap = new TreeMap(new Comparator() {
//            @Override
//            public int compare(Object o1, Object o2) {
//                // 按照传入的 key 的大小进行排序
//                String str1 = (String) o1;
//                String str2 = (String) o2;
//                return str1.compareTo(str2);
//                // 按照key 的长度比较
                return str1.length() - str2.length();
//            }
//        });

        treeMap.put("jack","杰克");
        treeMap.put("tom","汤姆");
        treeMap.put("kristina","克瑞斯提诺");
        treeMap.put("smith","斯密斯");

        System.out.println(treeMap);

        /**
         * 源码:
         * 第一步:使用TreeMap的构造器,在构造器传入 比较器对象的引用
         *     public TreeMap(Comparator<? super K> comparator) {
         *         this.comparator = comparator;完成 comparator属性的初始化
         *     }
         *
         * 第二步:执行 put 方法
         *
         *     public V put(K key, V value) {
         *     由于第一次添加所以 root的值为 null: private transient Entry<K,V> root;
         *         Entry<K,V> t = root;
         *         if (t == null) {所以第一次添加时会执行这里的代码
         *         下面调用compare方法是防止传入 null,可以传入null会抛出空指针异常
         *             compare(key, key); // type (and possibly null) check
         *
         *             root = new Entry<>(key, value, null); new一个Entry完成对象属性初始化
         *             size = 1; 容量加1
         *             modCount++; 修改次数加1
         *             return null;
         *         }
         *         int cmp;
         *         Entry<K,V> parent;
         *         // split comparator and comparable paths
         *         Comparator<? super K> cpr = comparator; 将比较器赋给 cpr: private final Comparator<? super K> comparator;
         *         if (cpr != null) { 如果比较不为null 执行这里代码
         *             do {
         *                 parent = t;
         *                 cmp = cpr.compare(key, t.key); 动态绑定的执行匿名内部中的 compare方法
         *                 if (cmp < 0)
         *                     t = t.left;
         *                 else if (cmp > 0)
         *                     t = t.right;
         *                 else
         *                     return t.setValue(value); 如果当比较器返回的值相等时,则将原来的value值替换成传入的value值
         *             } while (t != null);
         *         }
         *         else { 如果比较为null 执行这里代码
         *             if (key == null)
         *                 throw new NullPointerException();
         *             @SuppressWarnings("unchecked")
         *                 Comparable<? super K> k = (Comparable<? super K>) key;
         *             do {
         *                 parent = t;
         *                 cmp = k.compareTo(t.key);
         *                 if (cmp < 0)
         *                     t = t.left;
         *                 else if (cmp > 0)
         *                     t = t.right;
         *                 else
         *                     return t.setValue(value);
         *             } while (t != null);
         *         }
         *         Entry<K,V> e = new Entry<>(key, value, parent);
         *         if (cmp < 0)
         *             parent.left = e;
         *         else
         *             parent.right = e;
         *         fixAfterInsertion(e);
         *         size++;
         *         modCount++;
         *         return null;
         *     }
         */
    }
}
package com.hspedu.map_;

import java.util.Comparator;
import java.util.TreeMap;


@SuppressWarnings({"all"})
public class TreeMap_ {
    public static void main(String[] args) {

        //使用默认的构造器,创建TreeMap, 是无序的(也没有排序)
        /*
            老韩要求:按照传入的 k(String) 的大小进行排序
         */
//        TreeMap treeMap = new TreeMap();
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //按照传入的 k(String) 的大小进行排序
                //按照K(String) 的长度大小排序
                //return ((String) o2).compareTo((String) o1);
                return ((String) o2).length() - ((String) o1).length();
            }
        });
        treeMap.put("jack", "杰克");
        treeMap.put("tom", "汤姆");
        treeMap.put("kristina", "克瑞斯提诺");
        treeMap.put("smith", "斯密斯");

        System.out.println("treemap=" + treeMap);

        /*

            解读源码:
            1. 构造器. 把传入的实现了 Comparator接口的匿名内部类(对象),传给给TreeMap的comparator
             public TreeMap(Comparator<? super K> comparator) {
                this.comparator = comparator;
            }
            2. 调用put方法
            2.1 第一次添加, 把k-v 封装到 Entry对象,放入root
            Entry<K,V> t = root;
            if (t == null) {
                compare(key, key); // type (and possibly null) check

                root = new Entry<>(key, value, null);
                size = 1;
                modCount++;
                return null;
            }
            2.2 以后添加
            Comparator<? super K> cpr = comparator;
            if (cpr != null) {
                do { //遍历所有的key , 给当前key找到适当位置
                    parent = t;
                    cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的compare
                    if (cmp < 0)
                        t = t.left;
                    else if (cmp > 0)
                        t = t.right;
                    else  //如果遍历过程中,发现准备添加Key 和当前已有的Key 相等,就不添加
                        return t.setValue(value);
                } while (t != null);
            }
         */

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值