
在本教程中,我们将借助示例学习Java TreeMap类及其操作。
Java 集合框架的TreeMap类提供了树形数据结构实现。
它继承了NavigableMap接口。

创建一个TreeMap
为了创建TreeMap,我们必须首先导入java.util.TreeMap包。 导入程序包后,可以使用以下方法在Java中创建TreeMap。
TreeMap<Key, Value> numbers = new TreeMap<>();
在上面的代码中,我们创建了一个没有任何参数的名为numbers的TreeMap。在本示例中,TreeMap中的元素是自然排序的(升序)。
但是,我们可以通过使用Comparator接口自定义元素的排序。我们将在本教程的后面部分中学习它。
这里,
- Key - 用于关联map中每个元素(值)的唯一标识符 
- Value - map中与键相关联的元素 
TreeMap的方法
TreeMap类提供了各种方法,允许我们对映射执行操作。
将元素插入TreeMap
- put() - 将指定的键/值映射(条目)插入到映射中 
- putAll() - 将指定映射中的所有条目插入到此映射中 
- putIfAbsent() - 如果映射中不存在指定的键,则将指定的键/值映射插入到map中 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        //创建偶数的TreeMap
        TreeMap<String, Integer> evenNumbers = new TreeMap<>();
        // 使用 put()
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);
        // 使用 putIfAbsent()
        evenNumbers.putIfAbsent("Six", 6);
        System.out.println("偶数的TreeMap: " + evenNumbers);
        //Creating TreeMap of numbers
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("One", 1);
        // 使用 putAll()
        numbers.putAll(evenNumbers);
        System.out.println("TreeMap 的数字: " + numbers);
    }
}输出结果
偶数的TreeMap: {Four=4, Six=6, Two=2}
TreeMap 的数字: {Four=4, One=1, Six=6, Two=2}访问TreeMap元素
1.使用entrySet(),keySet()和values()
- entrySet() - 返回TreeMap的所有键/值映射(条目)的集合 
- keySet() - 返回TreeMap的所有键的集合 
- values() - 返回TreeMap的所有图的集合 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("TreeMap: " + numbers);
        // 使用 entrySet()
        System.out.println("Key/Value 映射: " + numbers.entrySet());
        // 使用 keySet()
        System.out.println("Keys: " + numbers.keySet());
        // 使用 values()
        System.out.println("Values: " + numbers.values());
    }
}输出结果
TreeMap: {One=1, Three=3, Two=2}
Key/Value 映射: [One=1, Three=3, Two=2]
Keys: [One, Three, Two]
Values: [1, 3, 2]2.使用get() 和 getOrDefault()
- get() - 返回与指定键关联的值。如果找不到键,则返回null。 
- getOrDefault() - 返回与指定键关联的值。如果找不到键,则返回指定的默认值。 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("TreeMap: " + numbers);
        // 使用 get()
        int value1 = numbers.get("Three");
        System.out.println("使用 get(): " + value1);
        // 使用 getOrDefault()
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("使用 getOrDefault(): " + value2);
    }
}输出结果
TreeMap: {One=1, Three=3, Two=2}
使用 get(): 3
使用 getOrDefault(): 5在这里,getOrDefault()方法没有找到键Five。因此,它返回指定的默认值5。
删除TeeMap元素
- remove(key) - 返回并从TreeMap中删除与指定键关联的条目 
- remove(key, value) -仅当指定键与指定值相关联时才从映射中删除条目,并返回布尔值 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("TreeMap: " + numbers);
        //具有单参数删除方法
        int value = numbers.remove("Two");
        System.out.println("被删除的值: " + value);
        //具有两个参数的删除方法
        boolean result = numbers.remove("Three", 3);
        System.out.println("条目 {Three=3} 被删除? " + result);
        System.out.println("更新后的TreeMap: " + numbers);
    }
}输出结果
TreeMap: {One=1, Three=3, Two=2}
被删除的值 = 2
条目 {Three=3} 被删除? True
更新后的TreeMap: {One=1}替换TreeMap元素
- replace(key, value)-用key新的替换指定映射的值value 
- replace(key, old, new) -仅当旧值已与指定键关联时,才用新值替换旧值 
- replaceAll(function) -用指定的结果替换map的每个值 function 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        System.out.println("Original TreeMap: " + numbers);
        // 使用 replace()
        numbers.replace("Second", 22);
        numbers.replace("Third", 3, 33);
        System.out.println("TreeMap使用replace()方法: " + numbers);
        // 使用 replaceAll()
        numbers.replaceAll((key, oldValue) -> oldValue + 2);
        System.out.println("TreeMap使用replaceAll()方法: " + numbers);
    }
}输出结果
Original TreeMap: {First=1, Second=2, Third=3}
TreeMap使用replace()方法: {First=1, Second=22, Third=33}
TreeMap使用replaceAll()方法: {First=3, Second=24, Third=35}在上述程序中,注意语句
numbers.replaceAll((key, oldValue) -> oldValue + 2);
在这里,我们传递了一个lambda表达式作为参数。
replaceAll()方法访问map的所有条目。然后,它将所有元素替换为新值(从lambda表达式返回)。
导航方法
因为TreeMap类实现了NavigableMap,所以它提供了在TreeMap元素上导航的各种方法。
1.第一个和最后一个方法
- firstKey() - 返回map的第一个键 
- firstEntry() - 返回映射的第一个键的键/值映射 
- lastKey() - 返回map的最后一个键 
- lastEntry() - 返回映射的最后一个键的键/值映射 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        System.out.println("TreeMap: " + numbers);
        // 使用 the firstKey() 方法
        String firstKey = numbers.firstKey();
        System.out.println("第一个键: " + firstKey);
        // 使用 the lastKey() 方法
        String lastKey = numbers.lastKey();
        System.out.println("最后一个键: " + lastKey);
        // 使用 firstEntry() 方法
        System.out.println("第一项: " + numbers.firstEntry());
        // 使用 the lastEntry() 方法
        System.out.println("最后一项: " + numbers.lastEntry());
    }
}输出结果
TreeMap: {First=1, Second=2, Third=3}
第一个键: First
最后一个键: Third
第一项: First=1
最后一项: Third=32.向上,向下,上下限方法
- HigherKey() - 返回大于指定键的那些键中的最小的键。 
- HigherEntry() - 返回与所有大于指定键的键中最小的键相关的条目。 
- lowerKey() - 返回所有小于指定键的最大键。 
- lowerEntry() - 返回与所有小于指定键的键中最大的键关联的条目。 
- ceilingKey() - 返回大于指定键的那些键中的最小的键。如果映射中存在作为参数传递的键,则它将返回该键。 
- ceilingEntry() - 返回与大于指定键的那些键中最小的键相关的条目。如果映射中存在与传递给自变量的键关联的条目,则返回与该键关联的条目。 
- floorKey() - 返回小于指定键的那些键中最大的键。如果存在作为参数传递的键,它将返回该键。 
- floorEntry() - 返回与小于指定键的那些键中最大的键相关的条目。如果存在作为参数传递的键,它将返回该键。 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 5);
        numbers.put("Third", 4);
        numbers.put("Fourth", 6);
        System.out.println("TreeMap: " + numbers);
        // 使用 higher()
        System.out.println("使用 higherKey(): " + numbers.higherKey("Fourth"));
        System.out.println("使用 higherEntry(): " + numbers.higherEntry("Fourth"));
        // 使用 lower()
        System.out.println("\n使用 lowerKey(): " + numbers.lowerKey("Fourth"));
        System.out.println("使用 lowerEntry(): " + numbers.lowerEntry("Fourth"));
        // 使用 ceiling()
        System.out.println("\n使用 ceilingKey(): " + numbers.ceilingKey("Fourth"));
        System.out.println("使用 ceilingEntry(): " + numbers.ceilingEntry("Fourth"));
        // 使用 floor()
        System.out.println("\n使用 floorKey(): " + numbers.floorKey("Fourth"));
        System.out.println("使用 floorEntry(): " + numbers.floorEntry("Fourth"));
    }
}输出结果
TreeMap: {First=1, Fourth=6, Second=5, Third=4}
使用 higherKey(): Second
使用 higherEntry(): Second=5
使用 lowerKey(): First
使用 lowerEntry(): First=1
使用 ceilingKey(): Fourth
使用 ceilingEntry(): Fourth=6
使用 floorkey(): Fourth
使用 floorEntry(): Fourth=63. pollFirstEntry()和pollLastEntry()方法
- pollFirstEntry() - 返回并删除与映射的第一个键关联的条目 
- pollLastEntry() -返回并删除与映射的最后一个键关联的条目 
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        System.out.println("TreeMap: " + numbers);
        //使用 the pollFirstEntry() 方法
        System.out.println("使用 pollFirstEntry(): " + numbers.pollFirstEntry());
        // 使用 the pollLastEntry() 方法
        System.out.println("使用 pollLastEntry(): " + numbers.pollLastEntry());
        System.out.println("更新后的TreeMap: " + numbers);
    }
}输出结果
TreeMap: {First=1, Second=2, Third=3}
使用 pollFirstEntry(): First=1
使用 pollLastEntry(): Third=3
更新后的TreeMap: {Second=2}4. headMap(),tailMap()和subMap()方法
headMap(key,booleanValue)
headMap()方法返回指定键Key(作为参数传递)之前treemap的所有键/值对。
booleanValue参数是可选的。默认值为false。
如果booleanValue为true,则该方法还包括指定key的键/值对。
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        numbers.put("Fourth", 4);
        System.out.println("TreeMap: " + numbers);
        System.out.println("\n使用 headMap() 方法:");
        // headMap() 使用默认 booleanValue为false
        System.out.println("没有指定布尔值: " + numbers.headMap("Fourth"));
        // headMap()使用指定 booleanValue 为 true
        System.out.println("指定布尔值为true: " + numbers.headMap("Fourth", true));
    }
}输出结果
TreeMap: {First=1, Fourth=4, Second=2, Third=3}
使用 headMap() 方法: 
没有指定布尔值: {First=1}
指定布尔值为true: {First=1, Fourth=4}tailMap(key,booleanValue)
tailMap()方法从指定键(作为参数传递)开始返回树图的所有键/值对。
booleanValue是一个可选的参数。默认值为true。
如果booleanValue为false,则该方法不包含指定key的键/值对。
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        numbers.put("Fourth", 4);
        System.out.println("TreeMap: " + numbers);
        System.out.println("\n使用 tailMap() 方法:");
        // tailMap() booleanValue使用默认值true
        System.out.println("booleanValue使用默认true: " + numbers.tailMap("Second"));
        // tailMap() booleanValue 使用指定值false
        System.out.println("booleanValue使用指定false : " + numbers.tailMap("Second", false));
    }
}输出结果
TreeMap: {First=1, Fourth=4, Second=2, Third=3}
使用 tailMap() 方法:
booleanValue使用默认true: {Second=2, Third=3}
booleanValue使用指定false: {Third=3}subMap(k1,bV1,k2,bV2)
subMap()方法返回与k1和k2之间的键相关联的所有条目,包括k1的条目。
bV1和bV2是可选的布尔参数。 bV1的默认值为true,bV2的默认值为false。
如果bV1为false,则该方法返回与k1和k2之间的键关联的所有条目,但不包括k1的条目。
如果bV2为true,则该方法返回与k1和k2之间的键关联的所有条目,包括k2的条目。
例如,
import java.util.TreeMap;
class Main {
    public static void main(String[] args) {
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        numbers.put("Fourth", 4);
        System.out.println("TreeMap: " + numbers);
        System.out.println("\n使用 subMap() 方法:");
        // tailMap() 使用默认布尔值
        System.out.println("使用默认布尔值: " + numbers.subMap("Fourth", "Third"));
        // tailMap() 指定布尔值
        System.out.println("指定布尔值: " + numbers.subMap("Fourth", false, "Third", true));
    }
}输出结果
TreeMap: {First=1, Fourth=2, Second=2, Third=3}
使用 subMap() 方法:
使用默认布尔值: {Fourth=4, Second=2}
指定布尔值: {Second=2, Third=3}TreeMap的其他方法
| 方法 | 描述 | 
|---|---|
| clone() | 创建TreeMap副本 | 
| containsKey() | 搜索TreeMap指定的键,并返回布尔结果 | 
| containsValue() | 在TreeMap中搜索指定的值并返回布尔结果 | 
| size() | 返回的大小 TreeMap | 
| clear() | 从中删除所有条目 TreeMap | 
TreeMap 比较器
在以上所有示例中,treemap元素都自然排序(以升序排列)。但是,我们也可以自定义键的顺序。
为此,我们需要基于对树图中的键进行排序的方式来创建自己的比较器类。例如,
import java.util.TreeMap;
import java.util.Comparator;
class Main {
    public static void main(String[] args) {
        //使用自定义比较器创建treemap
        TreeMap<String, Integer> numbers = new TreeMap<>(new CustomComparator());
        numbers.put("First", 1);
        numbers.put("Second", 2);
        numbers.put("Third", 3);
        numbers.put("Fourth", 4);
        System.out.println("TreeMap: " + numbers);
    }
    //创建一个比较器类
    public static class CustomComparator implements Comparator<String> {
        @Override
        public int compare(String number1, String number2) {
            int value =  number1.compareTo(number2);
            //元素以相反的顺序排序
            if (value > 0) {
                return -1;
            }
            else if (value < 0) {
                return 1;
            }
            else {
                return 0;
            }
        }
    }
}输出结果
TreeMap: {Third=3, Second=2, Fourth=4, First=1}在上面的示例中,我们创建了一个treemap,将CustomComparator类作为参数传递。
CustomComparator类实现了Comparator接口。
然后重写compare()方法,以相反顺序排列元素。
