Java TreeMap

TreeMap 类是 Java 集合框架 的一部分,它提供了树形数据结构的实现。

它实现了 NavigableMap 接口

Java TreeMap class implements the Map interface.


创建 TreeMap

为了创建 TreeMap,我们必须首先导入 java.util.TreeMap 包。导入包后,我们可以在 Java 中这样创建 TreeMap

TreeMap<Key, Value> numbers = new TreeMap<>();

在上面的代码中,我们创建了一个名为 numbersTreeMap,没有提供任何参数。在这种情况下,TreeMap 中的元素将自然排序(升序)。

但是,我们可以使用 Comparator 接口来自定义元素的排序。我们将在本教程后面介绍这一点。

这里,

  • Key - 用于将 map 中的每个元素(值)关联起来的唯一标识符
  • - 在 map 中由键关联的元素

TreeMap 方法

TreeMap 类提供了各种方法,使我们能够对 map 执行操作。


向 TreeMap 插入元素

  • put() - 将指定的键/值映射(条目)插入到 map 中
  • putAll() - 将指定映射中的所有条目插入到此映射中
  • putIfAbsent() - 如果指定键不在映射中,则将指定的键/值映射插入到映射中

例如,

import java.util.TreeMap;

class Main {
    public static void main(String[] args) {
        // Creating TreeMap of even numbers
        TreeMap<String, Integer> evenNumbers = new TreeMap<>();

        // Using put()
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);

        // Using putIfAbsent()
        evenNumbers.putIfAbsent("Six", 6);
        System.out.println("TreeMap of even numbers: " + evenNumbers);

        //Creating TreeMap of numbers
        TreeMap<String, Integer> numbers = new TreeMap<>();
        numbers.put("One", 1);

        // Using putAll()
        numbers.putAll(evenNumbers);
        System.out.println("TreeMap of numbers: " + numbers);
    }
}

输出

TreeMap of even numbers: {Four=4, Six=6, Two=2}
TreeMap of numbers: {Four=4, One=1, Six=6, Two=2}

访问 TreeMap 元素

1. 使用 entrySet()、keySet() 和 values()

  • entrySet() - 返回 treemap 中所有键/值映射(条目)的集合
  • keySet() - 返回 tree map 中所有键的集合
  • values() - 返回 tree map 中所有值的集合

例如,

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);

        // Using entrySet()
        System.out.println("Key/Value mappings: " + numbers.entrySet());

        // Using keySet()
        System.out.println("Keys: " + numbers.keySet());

        // Using values()
        System.out.println("Values: " + numbers.values());
    }
}

输出

TreeMap: {One=1, Three=3, Two=2}
Key/Value mappings: [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);

        // Using get()
        int value1 = numbers.get("Three");
        System.out.println("Using get(): " + value1);

        // Using getOrDefault()
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("Using getOrDefault(): " + value2);
    }
}

输出

TreeMap: {One=1, Three=3, Two=2}
Using get(): 3
Using getOrDefault(): 5

在此,getOrDefault() 方法找不到键 Five。因此,它返回指定的默认值 5


移除 TreeMap 元素

  • remove(key) - 从 TreeMap 中返回并移除与指定键关联的条目
  • remove(key, value) - 仅当指定键与指定值关联时才从 map 中移除条目,并返回一个布尔值

例如,

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);

        // remove method with single parameter
        int value = numbers.remove("Two");
        System.out.println("Removed value: " + value);

        // remove method with two parameters
        boolean result = numbers.remove("Three", 3);
        System.out.println("Is the entry {Three=3} removed? " + result);

        System.out.println("Updated TreeMap: " + numbers);
    }
}

输出

TreeMap: {One=1, Three=3, Two=2}
Removed value = 2
Is the entry {Three=3} removed? True
Updated TreeMap: {One=1}

替换 TreeMap 元素

  • replace(key, value) - 用新 替换由指定的 映射的值
  • replace(key, old, new) - 仅当旧值已与指定键关联时,才用新值替换旧值
  • replaceAll(function) - 用指定的 函数 的结果替换 map 的每个值

例如,

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);

        // Using replace()
        numbers.replace("Second", 22);
        numbers.replace("Third", 3, 33);
        System.out.println("TreeMap using replace: " + numbers);

        // Using replaceAll()
        numbers.replaceAll((key, oldValue) -> oldValue + 2);
        System.out.println("TreeMap using replaceAll: " + numbers);
    }
}

输出

Original TreeMap: {First=1, Second=2, Third=3}
TreeMap using replace(): {First=1, Second=22, Third=33}
TreeMap using replaceAll(): {First=3, Second=24, Third=35}

在上面的程序中,请注意语句

numbers.replaceAll((key, oldValue) -> oldValue + 2);

在这里,我们传递了一个 Lambda 表达式 作为参数。

replaceAll() 方法访问 map 的所有条目。然后,它用新值(从 Lambda 表达式返回)替换所有元素。


由于 TreeMap 类实现了 NavigableMap,因此它提供了各种方法来遍历 treemap 的元素。

1. firstKey() 和 lastKey() 方法

  • firstKey() - 返回 map 的第一个键
  • firstEntry() - 返回 map 的第一个键的键/值映射
  • lastKey() - 返回 map 的最后一个键
  • lastEntry() - 返回 map 的最后一个键的键/值映射

例如,

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);

        // Using the firstKey() method
        String firstKey = numbers.firstKey();
        System.out.println("First Key: " + firstKey);

        // Using the lastKey() method
        String lastKey = numbers.lastKey();
        System.out.println("Last Key: " + lastKey);

        // Using firstEntry() method
        System.out.println("First Entry: " + numbers.firstEntry());


        // Using the lastEntry() method
        System.out.println("Last Entry: " + numbers.lastEntry());
    }
}

输出

TreeMap: {First=1, Second=2, Third=3}
First Key: First
Last Key: Third
First Entry: First=1
Last Entry: Third=3

2. ceilingKey()、floorKey()、higherKey() 和 lowerKey() 方法

  • 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);

        // Using higher()
        System.out.println("Using higherKey(): " + numbers.higherKey("Fourth"));
        System.out.println("Using higherEntry(): " + numbers.higherEntry("Fourth"));

        // Using lower()
        System.out.println("\nUsing lowerKey(): " + numbers.lowerKey("Fourth"));
        System.out.println("Using lowerEntry(): " + numbers.lowerEntry("Fourth"));

        // Using ceiling()
        System.out.println("\nUsing ceilingKey(): " + numbers.ceilingKey("Fourth"));
        System.out.println("Using ceilingEntry(): " + numbers.ceilingEntry("Fourth"));

        // Using floor()
        System.out.println("\nUsing floorKey(): " + numbers.floorKey("Fourth"));
        System.out.println("Using floorEntry(): " + numbers.floorEntry("Fourth"));


    }
}

输出

TreeMap: {First=1, Fourth=6, Second=5, Third=4}
Using higherKey(): Second
Using higherEntry(): Second=5

Using lowerKey(): First
Using lowerEntry(): First=1

Using ceilingKey(): Fourth
Using ceilingEntry(): Fourth=6

Using floorkey(): Fourth
Using floorEntry(): Fourth=6

3. pollFirstEntry() 和 pollLastEntry() 方法

  • pollFirstEntry() - 返回并移除与 map 的第一个键关联的条目
  • pollLastEntry() - 返回并移除与 map 的最后一个键关联的条目

例如,

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);

        //Using the pollFirstEntry() method
        System.out.println("Using pollFirstEntry(): " + numbers.pollFirstEntry());

        // Using the pollLastEntry() method
        System.out.println("Using pollLastEntry(): " + numbers.pollLastEntry());

        System.out.println("Updated TreeMap: " + numbers);

    }
}

输出

TreeMap: {First=1, Second=2, Third=3}
Using pollFirstEntry(): First=1
Using pollLastEntry(): Third=3
Updated TreeMap: {Second=2}

4. headMap()、tailMap() 和 subMap() 方法

headMap(key, booleanValue)

headMap() 方法返回 treemap 中指定 (作为参数传递)之前的所有键/值对。

booleanValue 参数是可选的。它的默认值为 false

如果传递 true 作为 booleanValue,该方法还将包含作为参数传递的 的键/值对。

例如,

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("\nUsing headMap() Method:");
        // Using headMap() with default booleanValue
        System.out.println("Without boolean value: " + numbers.headMap("Fourth"));

        // Using headMap() with specified booleanValue
        System.out.println("With boolean value: " + numbers.headMap("Fourth", true));

    }
}

输出

TreeMap: {First=1, Fourth=4, Second=2, Third=3}

Using headMap() Method: 
Without boolean value: {First=1}
With boolean value: {First=1, Fourth=4}

tailMap(key, booleanValue)

tailMap() 方法返回 treemap 中从指定 (作为参数传递)开始的所有键/值对。

booleanValue 是一个可选参数。其默认值为 true

如果传递 false 作为 booleanValue,该方法将不包含指定 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("\nUsing tailMap() Method:");
        // Using tailMap() with default booleanValue
        System.out.println("Without boolean value: " + numbers.tailMap("Second"));

        // Using tailMap() with specified booleanValue
        System.out.println("With boolean value: " + numbers.tailMap("Second", false));

    }
}

输出

TreeMap: {First=1, Fourth=4, Second=2, Third=3}

Using tailMap() Method:
Without boolean value: {Second=2, Third=3}
With boolean value: {Third=3}

subMap(k1, bV1, k2, bV2)

subMap() 方法返回 k1k2 之间所有键关联的条目,包括 k1 的条目。

bV1bV2 是可选的布尔参数。 bV1 的默认值为 truebV2 的默认值为 false

如果传递 false 作为 bV1,该方法将返回 k1k2 之间所有键关联的条目,但不包括 k1 的条目。

如果传递 true 作为 bV2,该方法将返回 k1k2 之间所有键关联的条目,包括 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("\nUsing subMap() Method:");
        // Using subMap() with default booleanValue
        System.out.println("Without boolean value: " + numbers.subMap("Fourth", "Third"));

        // Using subMap() with specified booleanValue
        System.out.println("With boolean value: " + numbers.subMap("Fourth", false, "Third", true));

    }
}

输出

TreeMap: {First=1, Fourth=2, Second=2, Third=3}

Using subMap() Method:
Without boolean value: {Fourth=4, Second=2}
With boolean value: {Second=2, Third=3}

TreeMap 的其他方法

方法 描述
clone() 创建 TreeMap 的副本
containsKey() 搜索 TreeMap 中指定的键并返回布尔结果
containsValue() 搜索 TreeMap 中指定的值并返回布尔结果
size() 返回 TreeMap 的大小
clear() 移除 TreeMap 中的所有条目

TreeMap Comparator

在上面的所有示例中,treemap 元素都是自然排序(升序)。但是,我们也可以自定义键的顺序。

为此,我们需要创建自己的比较器类,treemap 中的键将根据该类进行排序。例如,

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

class Main {
    public static void main(String[] args) {

        // Creating a treemap with a customized comparator
        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);
    }

    // Creating a comparator class
    public static class CustomComparator implements Comparator<String> {

        @Override
        public int compare(String number1, String number2) {
            int value =  number1.compareTo(number2);

            // elements are sorted in reverse order
            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() 方法以按反序对元素进行排序。

要了解更多信息,请访问 Java Comparator (Oracle 官方 Java 文档)

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战