TreeMap学习

一、概念

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

TreeMap 继承了 AbstractMap,AbstractMap 实现了 Map<K,V> 接口。所以TreeMap 具有 Map 的特性。定义如下:

	
    /**
     * The comparator used to maintain order in this tree map, or
     * null if it uses the natural ordering of its keys.
     * 比较器
     */
    
	private final Comparator<? super K> comparator;
	// 根节点
    private transient Entry<K,V> root;

    /**
     * The number of entries in the tree
     * 节点数量
     */
    private transient int size = 0;

    /**
     * The number of structural modifications to the tree.
     * 修改次数
     */
    private transient int modCount = 0;

Entry 的结构,红黑二叉树节点

		K key;
        V value;
        Entry<K,V> left;
        Entry<K,V> right;
        Entry<K,V> parent;
        boolean color = BLACK;

特点:

1. 底层结构为红黑二叉树,增删改查的效率都比较高
2. 默认会对键进行排序,所以键必须实现自然排序和定制排序中的一种
3. 存放的元素是无序的(指的是元素顺序与插入顺序不一致)

4. key 重复进行覆盖指,比较器按照键中具体的排序规则返回 0,与key.equals() 无关
5. key 不可以为null(需要排序)
5. 强调:使用map接口的实现类时,切记不要修改key的属性值,否则就会找不到key 所对应的 value值

如果要使用 TreeMap 存储数据,必须能对 key 进行排序,其中有两种排序方法
1. 自然排序算法,需要类实现 Comparable 接口,重写 compareTo()方法
2. 定制排序 Comparator,一般采用匿名内部类的方式

二、举例

Person 类举例
要求 key必须可排序, Person 按照身高进行排序
1、Person 类未实现 Comparable 接口时报错 Person cannot be cast to java.lang.Comparable
2、自然排序,Person 类实现 Comparable 接口,重写 compareTo()方法按照身高升序排序
3、定制比较器,实现匿名类重写 compare()方法按照身高降序排序

public class Person implements Comparable<Person>{
    
    
    String name;
    int high;

   public  Person(String name,int high){
    
    
       this.name = name;
       this.high = high;
   }

    public String toString(){
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", high=" + high +
                '}';
    }
    /*
        按照身高 升序
     */
    @Override
    public int compareTo(@NotNull Person person) {
    
    
       if(person.high > this.high){
    
    
           return -1;
       }else if(person.high < this.high) {
    
    
           return 1;
       }
       return 0;
    }
}

测试:

/*
        key必须可排序, Person 按照身高进行排序
     */
    public static void test2() {
    
    

        log.info("1、Person 类未实现 Comparable 接口时报错  Person cannot be cast to java.lang.Comparable");
        log.info("2、Person 类实现 Comparable 接口,重写 compareTo()方法按照身高升序排序");
        //输出:
        // name:Student{name='小王', high=160}, high:88
        // name:Student{name='小张', high=170}, high:80
        // name:Student{name='小李', high=180}, high:90

        TreeMap<Person, Integer> personInfoMap = new TreeMap<>();
        personInfoMap.put(new Person("小张", 170), 80);
        personInfoMap.put(new Person("小王", 160), 88);
        personInfoMap.put(new Person("小李", 180), 90);

        for (Map.Entry<Person, Integer> personIntegerEntry : personInfoMap.entrySet()) {
    
    
            log.info("name:{}, high:{}", personIntegerEntry.getKey(),personIntegerEntry.getValue());
        }



        log.info("3、定制比较器,实现匿名类重写 compare()方法按照身高降序排序");
        //输出:
        // name:Student{name='小红', high=166}, high:80
        // name:Student{name='小芳', high=163}, high:90
        // name:Student{name='小丽', high=160}, high:88
        TreeMap<Person, Integer> personInfoMap1 = new TreeMap<>(new Comparator<Person>() {
    
    
            @Override
            public int compare(Person o1, Person o2) {
    
    
                if(o1.high > o2.high){
    
    
                    return -1;
                }else if(o1.high < o2.high){
    
    
                    return 1;
                }
                return 0;
            }
        });

        personInfoMap1.put(new Person("小红", 166), 80);
        personInfoMap1.put(new Person("小丽", 160), 88);
        personInfoMap1.put(new Person("小芳", 163), 90);

        personInfoMap1.forEach((k,value) ->{
    
    
            log.info("name:{}, high:{}", k,value);
        });
    }

猜你喜欢

转载自blog.csdn.net/Misszhoudandan/article/details/131481054
今日推荐