Java TreeMap
TreeMap 底层使用树结构实现了键值对存储数据,它存储的键值对条目是有序的和可导航的。在本教程中,我们将通过示例了解 Java TreeMap 类及其用法。
在本教程中,我们将通过示例了解 Java TreeMap 类及其用法。
TreeMap
底层使用树结构实现了键值对存储数据,它存储的键值对条目是有序的和可导航的。 TreeMap
实现了实现了 NavigableMap 接口。
创建 TreeMap
TreeMap
是一个类,我们可以直接使用它的构造方法创建对象。
TreeMap<Key, Value> numbers = new TreeMap<>();
在上面的代码中,我们使用默认的构造方法创建了一个名为 numbers
的 TreeMap
实例。在这种情况下, TreeMap
中的元素自然排序(升序)。
我们也可以在构造方法中传入 Comparator
比较器对象来自定义元素的排序。我们将在本教程的后面部分介绍它。
这里,
Key
- SortedMap 中键的数据类型Value
- SortedMap 中值的数据类型
TreeMap 的方法
TreeMap
类提供许多方法,以便我们能够控制 TreeMap
对象和其中的条目。
将元素插入到 TreeMap
put()
- 将指定的键值对条目插入到 Map 中putAll()
- 将指定 Map 中的所有条目插入到此 Map 中putIfAbsent()
- 如果 Map 中不存在指定的键,则将指定的键值对条目插入到 Map 中
例如,
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
// 一个 TreeMap 对象
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("evenNumbers: " + evenNumbers);
// 另一个 TreeMap 对象
TreeMap<String, Integer> numbers = new TreeMap<>();
numbers.put("One", 1);
// Using putAll()
numbers.putAll(evenNumbers);
System.out.println("numbers: " + numbers);
}
}
输出
evenNumbers: {Four=4, Six=6, Two=2}
numbers: {Four=4, One=1, Six=6, Two=2}
访问 TreeMap 元素
-
使用 entrySet()、keySet() 和 values()
entrySet()
- 返回所有键值对条目的集合keySet()
- 返回 TreeMap 中的所有键的集合values()
- 返回 TreeMap 中的所有值的集合
例如,
import java.util.TreeMap; public 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]
-
使用 get() 和 getOrDefault()
get()
- 返回与指定键关联的值。如果未找到键,则返回 null。getOrDefault()
- 返回与指定键关联的值。如果未找到键,则返回指定的默认值。
例如,
import java.util.TreeMap; public 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("get(\"Three\"): " + value1); // Using getOrDefault() int value2 = numbers.getOrDefault("Five", 5); System.out.println("getOrDefault(\"Five\", 5): " + value2); } }
输出
TreeMap: {One=1, Three=3, Two=2} get("Three"): 3 getOrDefault("Five", 5): 5
在这里,该
getOrDefault()
方法没有找到键"Five"
,因此它返回指定的默认值5
。
删除 TeeMap 元素
remove(key)
- 从 TreeMap 中删除并返回与指定键关联的条目remove(key, value)
- 仅当指定的键与指定的值相关联时才从 Map 中删除条目, 并返回 true 表示成功,false 表示失败。
例如,
import java.util.TreeMap;
public 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)
- 使用指定的接口函数运算每个条目的结果替换每个条目的值
例如,
import java.util.TreeMap;
public 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 表达式 “Java lambda 表达式”)作为参数。
replaceAll()
对 Map 中的所有条目 lambda 表达式进行计算,并用返回的值替换条目中的值。
导航方法
TreeMap
类实现了 NavigableMap
接口,它实现了 NavigableMap
接口定义的用于导航元素的方法。
first 和 last 相关的方法
firstKey()
- 返回 Map 的第一个键firstEntry()
- 返回映射的第一个键的键值对条目lastKey()
- 返回 Map 的最后一个键lastEntry()
- 返回 Map 最后一个键的键值对条目
例如,
import java.util.TreeMap;
public 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
搜索最接近的匹配值方法
higherEntry()
- 返回键大于指定键的所有条目中键最小的条目higherKey()
- 返回大于指定键的键中最小的键lowerEntry()
- 返回键小于指定键的所有条目中键最大的条目lowerKey()
- 返回那些小于指定键的键中的最大的键ceilingEntry()
- 返回键大于或等于指定键的所有条目中键最小的条目ceilingKey()
- 返回大于或等于指定键的键中的最小的键floorEntry()
- 返回键小于或等于指定键的所有条目中键最大的条目floorKey()
- 返回小于或等于指定键的键中的最大的键
例如,
import java.util.TreeMap;
public 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("higherKey(\"Fourth\"): " + numbers.higherKey("Fourth"));
System.out.println("higherEntry(\"Fourth\"): " + numbers.higherEntry("Fourth"));
// Using lower()
System.out.println("\nlowerKey(\"Fourth\"): " + numbers.lowerKey("Fourth"));
System.out.println("lowerEntry(\"Fourth\"): " + numbers.lowerEntry("Fourth"));
// Using ceiling()
System.out.println("\nceilingKey(\"Fourth\"): " + numbers.ceilingKey("Fourth"));
System.out.println("ceilingEntry(\"Fourth\"): " + numbers.ceilingEntry("Fourth"));
// Using floor()
System.out.println("\nfloorKey(\"Fourth\"): " + numbers.floorKey("Fourth"));
System.out.println("floorEntry(\"Fourth\"): " + numbers.floorEntry("Fourth"));
}
}
输出
TreeMap: {First=1, Fourth=6, Second=5, Third=4}
higherKey("Fourth"): Second
higherEntry("Fourth"): Second=5
lowerKey("Fourth"): First
lowerEntry("Fourth"): First=1
ceilingKey("Fourth"): Fourth
ceilingEntry("Fourth"): Fourth=6
floorKey("Fourth"): Fourth
floorEntry("Fourth"): Fourth=6
pollFirstEntry() 和 pollLastEntry() 方法
pollFirstEntry()
- 删除并返回与第一个键关联的条目pollLastEntry()
- 删除并返回与最后一个键关联的条目
例如,
import java.util.TreeMap;
public 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}
headMap(toKey, inclusive)
headMap(toKey, inclusive)
方法返回由键位于 toKey
所在条目之前的所有条目组成的 NavigableMap
对象。
inclusive
参数如果为 false
,该方法返回的 Map 中不包括 toKey
所在的条目;如果为 true
,该方法返回的集合中包括 toKey
所在的条目。
例如,
import java.util.TreeMap;
public 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(fromKey, inclusive)
tailMap(fromKey, inclusive)
方法返回由键位于 fromKey
所在条目之后的所有条目组成的 NavigableMap
对象。
inclusive
参数如果为 false
,该方法返回的 Map 中不包括 fromKey
所在的条目;如果为 true
,该方法返回的集合中包括 fromKey
所在的条目。
例如,
import java.util.TreeMap;
public 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(fromKey, fromInclusive, toKey, toInclusive)
subMap(fromKey, fromInclusive, toKey, toInclusive)
方法返回由键位于 fromKey
条目和 toKey
条目之间的所有条目组成的 NavigableMap
对象。
如果 fromInclusive
为 true
,则返回的 Map 中包括 fromKey
所在的条目, 为 false
则不包括 fromKey
所在的条目。
如果 toInclusive
为 true
,则返回的 Map 中包括 toKey
所在的条目, 为 false
则不包括 toKey
所在的条目。
例如,
import java.util.TreeMap;
public 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=4, 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 比较器
在上面的所有示例中,TreeMap 的元素是根据键自然排序的(按升序)。但是我们也可以自定义键的顺序。
我们可以根据自己的需求创建我们自定义的比较器类。例如,
import java.util.TreeMap;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
// 在构造方法中传入比较器
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) {
// 以自然排序相反的顺序排列
return number1.compareTo(number2) * -1;
}
}
}
输出
TreeMap: {Third=3, Second=2, Fourth=4, First=1}
在上面的例子中,我们创建 TreeMap 对象时,在构造方法中使用自定义比较器对象作为参数。
关于自定义比较器的说明:
- 自定义比较器需要实现
Comparator
接口 compare(a, b)
方法需要传入每次参与比较的 2 个参数,返回值需满足下列条件:- 如果
a > b
返回大于0
的整数 - 如果
a < b
返回小于0
的整数 - 如果
a = b
返回0
- 如果
然后我们重写了 compare()
方法以相反的顺序对元素进行排序。