TreeMap
类是 Java 集合框架 的一部分,它提供了树形数据结构的实现。
它实现了 NavigableMap 接口。
创建 TreeMap
为了创建 TreeMap
,我们必须首先导入 java.util.TreeMap
包。导入包后,我们可以在 Java 中这样创建 TreeMap
。
TreeMap<Key, Value> numbers = new TreeMap<>();
在上面的代码中,我们创建了一个名为 numbers 的 TreeMap
,没有提供任何参数。在这种情况下,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()
方法返回 k1 和 k2 之间所有键关联的条目,包括 k1 的条目。
bV1 和 bV2 是可选的布尔参数。 bV1 的默认值为 true
,bV2 的默认值为 false
。
如果传递 false
作为 bV1,该方法将返回 k1 和 k2 之间所有键关联的条目,但不包括 k1 的条目。
如果传递 true
作为 bV2,该方法将返回 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("\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 文档)。