ツリーマップの学習

1.コンセプト

public class TreeMap<K,V> extends AbstractMap<K,V>
実装 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. キーは繰り返し上書きされ、コンパレータはキー内の特定の並べ替え規則に従って 0 を返します。これは key.equals() とは関係ありません。
5. キーを null にすることはできません (ソートが必要です)。
5. 強調: マップ インターフェイスの実装クラスを使用するときは、キーの属性値を変更しないように注意してください。変更しないと、キーに対応する値が見つかりません。

TreeMap を使用してデータを保存する場合は、キーをソートできる必要があります。ソート方法は 2 つあります。
1. 自然な並べ替えアルゴリズムでは、クラスが Comparable インターフェイスを実装し、compareTo() メソッドを書き直す必要があります。
2. 通常は匿名の内部クラスを使用して、sort Comparator をカスタマイズします。

2、例

Person クラスの例
キーはソート可能である必要があり、パーソンは高さに従ってソートされます
1. パーソン クラスは Comparable インターフェイスを実装していないため、エラーが報告されます パーソンは java.lang.Comparable にキャストできません
2. 自然なソート、パーソン クラスは比較可能なインターフェイス、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