Java中的TreeMap

Java中的TreeMap

Java中的TreeMap是一种基于红黑树实现的有序映射表,它可以根据键的自然顺序或指定的比较器确定顺序。TreeMap通过红黑树的自平衡算法来维护 key-value 的有序映射表结构。

TreeMap的创建和访问

创建TreeMap的方式是调用无参构造函数:

TreeMap<K, V> treeMap = new TreeMap<>();

当插入键值对(key-value)到TreeMap中时,键(key)会按照自然顺序被插入到有序集合中,然后相应的值(value)也会被插入到该key对应的节点中。可以使用put方法向TreeMap中插入元素:

treeMap.put(1, "value1");
treeMap.put(3, "value3");
treeMap.put(2, "value2");

通过key在TreeMap中查找相应的值,可以使用get方法:

String value = treeMap.get(2);
System.out.println(value); // Output: value2

遍历TreeMap中元素

可以使用entrySet()方法获取TreeMap中的键值对Entry集合,然后遍历每个Entry,并输出对应的key和value:

for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
    System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

输出结果:

key: 1, value: value1
key: 2, value: value2
key: 3, value: value3

如果只需要遍历TreeMap中的key或者value,则可以分别使用keySet()方法和values()方法:

for (Integer key : treeMap.keySet()) {
    System.out.println("key: " + key);
}

for (String value : treeMap.values()) {
    System.out.println("value: " + value);
}

输出结果:

key: 1
key: 2
key: 3
value: value1
value: value2
value: value3

TreeMap的比较器

当元素的key不是基本数据类型时,可以通过指定比较器来比较元素的key。创建TreeMap时,可以通过传入一个比较器来代替自然顺序比较。比较器是通过Comparator接口来定义的,该接口包含两个方法:

int compare(T o1, T o2) // 比较o1和o2的大小关系,如果o1 < o2则返回负数,如果o1 > o2则返回正数,如果相等则返回0
boolean equals(Object obj) // 判断两个比较器是否相等

下面是一个使用比较器比较String对象的例子:

TreeMap<String, String> treeMapWithComparator = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
});

treeMapWithComparator.put("ABCD", "value1");
treeMapWithComparator.put("BCD", "value2");
treeMapWithComparator.put("CDE", "value3");

for (Map.Entry<String, String> entry : treeMapWithComparator.entrySet()) {
    System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

输出结果:

key: ABCD, value: value1
key: BCD, value: value2
key: CDE, value: value3

指定比较器后,元素的key按照指定的比较器进行比较,而不是按照key的自然顺序。

TreeMap的子Map

TreeMap提供了tailMap(), headMap() 和 subMap() 三个方法来获取TreeMap中的子Map。

tailMap(K fromKey, boolean inclusive)方法返回一个部分视图,其key大于等于fromKey。如果inclusive参数为true,则返回的部分视图中也包含fromKey对应的值。

TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(1, "value1");
treeMap.put(2, "value2");
treeMap.put(3, "value3");
treeMap.put(4, "value4");

SortedMap<Integer, String> subMap = treeMap.tailMap(2);
for (Map.Entry<Integer, String> entry : subMap.entrySet()) {
    System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

输出结果:

key: 2, value: value2
key: 3, value: value3
key: 4, value: value4

headMap(K toKey)方法返回一个部分视图,其key小于toKey。

SortedMap<Integer, String> subMap = treeMap.headMap(3);
for (Map.Entry<Integer, String> entry : subMap.entrySet()) {
    System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

输出结果:

key: 1, value: value1
key: 2, value: value2

subMap(K fromKey, K toKey)方法返回一个部分视图,其key介于fromKey和toKey之间。

SortedMap<Integer, String> subMap = treeMap.subMap(2, 4);
for (Map.Entry<Integer, String> entry : subMap.entrySet()) {
    System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}

输出结果:

key: 2, value: value2
key: 3, value: value3

TreeMap的删除

通过key从TreeMap中删除元素,可以使用remove()方法:

treeMap.remove(2);

当然,可以通过clear()方法一次性删除所有元素:

treeMap.clear();

TreeMap中的键和值的操作

TreeMap提供了firstKey()和lastKey()方法分别返回TreeMap中的第一个和最后一个key,还提供了firstEntry()和lastEntry()方法返回TreeMap中的第一个和最后一个Entry。此外,还提供了ceilingKey(K key)、floorKey(K key)、higherKey(K key)、lowerKey(K key)等方法分别返回 大于等于、小于等于、严格大于、严格小于指定key的最近的key。

TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(1, "value1");
treeMap.put(3, "value3");
treeMap.put(2, "value2");
treeMap.put(4, "value4");

System.out.println(treeMap.firstKey()); // Output: 1
System.out.println(treeMap.lastKey()); // Output: 4
System.out.println(treeMap.firstEntry()); // Output: 1=value1
System.out.println(treeMap.lastEntry()); // Output: 4=value4
System.out.println(treeMap.ceilingKey(2)); // Output: 2
System.out.println(treeMap.floorKey(2)); // Output: 2
System.out.println(treeMap.higherKey(2)); // Output: 3
System.out.println(treeMap.lowerKey(2)); // Output: 1

TreeMap的注意点

在使用TreeMap时,有以下注意点:

  • TreeMap是非线程安全的,如果需要在多线程环境下使用,则需要额外进行同步控制。
  • 对于非基本数据类型的key,需要同时实现hashCode()和equals()方法,以确保每个元素可以正确地放在相应的位置。
  • TreeMap的key必须是可比较的类型(实现了Comparable接口或者传入了比较器),否则将抛出ClassCastException异常。
  • TreeMap使用红黑树算法维护集合,因此插入、查询和删除操作的时间复杂度为O(logN)。

结论

TreeMap是Java中一种基于红黑树算法实现的有序映射表。TreeMap提供了插入、查询、删除、遍历以及获取子Map等方法,可以适用于多种用途。使用TreeMap时需要注意线程安全性、元素类型、key的可比性以及算法复杂度等方面的问题,才能保证程序的正确性和效率。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程