文章目录
往期:
- Collection集合工具类源码解读(一) — ArrayList 和 Vector
- Collection集合工具类源码解读(二) — LinkedList
- Collection集合工具类源码解读(三) — HashMap
- Collection集合工具类源码解读(四) — HashTable,HashSet,LinkedHashMap,LinkedHashSet
9、TreeMap
9.1 先看看属性
TreeMap就是一个Hash表内存红黑树的结构
- comparator:比较器,可以通过构造函数传入
- root:根节点指针
9.2 构造函数
- TreeMap():无参构造,默认自然排序
- TreeMap(Comparator<? super K> comparator):自定义排序方法
- TreeMap(Map<? extends K, ? extends V> m):传入一个Map复制,但是和无参构造一样自然排序
- TreeMap(SortedMap<K, ? extends V> m):传入一个SortedMap,使用SortedMap的比较器,同时复制其内容
9.3 put方法分析排序
写一个demo
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Object, Integer> treeMap = new TreeMap<>();
treeMap.put("c",1);
treeMap.put("a",1);
treeMap.put(new Person("xiaoming"),1);
treeMap.put("b",1);
treeMap.put(new Person("xiaohong"),1);
}
static class Person implements Comparable<Object>{
String name;
Person(String name){
this.name = name;
}
@Override
public int compareTo(Object o) {
if (o.getClass()==String.class)
return name.compareTo((String) o);
else if (o.getClass()==Person.class)
return name.compareTo(((Person) o).name);
else return 0;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
}
第一次put
- put方法第一次进入,必然进入第一个if,因为root为空
- 此时比较自己的key,这个compare方法先判断是否有比较器
- 用无参构造,没有比较器,默认用对应类型的
compareTo方法
- compareTo方法需要类型实现
Comparabled接口
,并且重写compareTo方法
才能做比较 - String类型默认有compareTo方法,是按字典顺序比较的,所以第一个"c"能put进去
- 自定义类型要实现
Comparabled接口
:如图,左侧不实现Comparabled接口是会抛异常的
- 用无参构造,没有比较器,默认用对应类型的
以后的put
- 第二次以及以后进入put就会直接到图上位置。先获得TreeMap的比较器
- 如果比较器不为空:用比较器比较
- 如果比较器为空:用compareTo方法比较
- 比较器或者compareTo方法都会返回一个值
cmp
,根据这个判断谁大谁小 - 然后将其插入相关位置,或者替换之前的元素
如果用比较器怎么写?
public static void main(String[] args) {
//传入一个Comparator,可以采用lambda表达式
TreeMap<Object, Integer> treeMap = new TreeMap<>((o1,o2)->{
if (o1.getClass()==String.class&&o2.getClass()==String.class){
return ((String) o1).compareTo((String) o2);
}
else if (o1.getClass()==Person.class&&o2.getClass()==Person.class){
return ((Person) o1).name.compareTo(((Person) o2).name);
}
else return 0;
});
treeMap.put("c",1);
treeMap.put("a",1);
treeMap.put(new Person("xiaoming"),1);
treeMap.put("b",1);
treeMap.put(new Person("xiaohong"),1);
System.out.println(treeMap);
}
static class Person{
String name;
Person(String name){
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
}
将demo重写,构造器传入一个Comparator,可以采用lambda表达式,lambda表达式里返回一个最后的int值就行了
9.4 一些常用API

如果Comparator不为空就用比较器比较排序之后再取值,如果为空就用compareTo比较
还有一些静态的方法:
这些静态方法为一些API提供支持:
firstEntry()
:获得第一个EntrylastEntry()
:获得最后一个EntrypollFirstEntry()
:删除第一个EntrypollLastEntry()
:删除最后一个Entry- 严格小于
lowerEntry(K key)
:获得一个key比传入key小的EntrylowerKey(K key)
:获得一个key比传入key小的Key
- 严格大于
higherEntry(K key)
:获得一个key比传入key大的EntryhigherKey(K key)
:获得一个key比传入key大的Key
- 小于等于
floorEntry(K key)
:获得一个key比传入key小,或者等于key的EntryfloorKey(K key)
:获得一个key比传入key小,或者等于key的Key
- 大于等于
ceilingEntry(K key)
:获得一个key比传入key大,或者等于key的EntryceilingKey(K key)
:获得一个key比传入key大,或者等于key的Key
- 一些其他的API
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
:返回一个从fromKey到toKey的NavigableMapsubMap(K fromKey, K toKey)
:返回一个从fromKey到toKey的SortedMapheadMap(K toKey, boolean fromInclusive)
:返回一个Key小于(或等于,如果fromInclusive为真)toKey的NavigableMapheadMap(K toKey)
:返回一个Key小于等于toKey的SortedMaptailMap(K fromKey, boolean fromInclusive)
:返回一个Key大于(或等于,如果fromInclusive为真)fromKey的NavigableMaptailMap(K fromKey)
:返回一个Key大于等于fromKey的SortedMap
10、TreeSet
10.1 先看看属性
- 一个NavigableMap,实际上,TreeMap就是实现NavigableMap接口的一个类
- 常量PRESENT,和HashSet里的用途一样
10.2 构造函数
-
TreeSet():无参构造,new一个TreeMap
-
TreeSet(Comparator<? super E> comparator):有参构造,new 一个TreeMap,自定义比较器
-
TreeSet(NavigableMap<E,Object> m):有参构造,传入一个NavigableMap,将内置的NavigableMap置为该map
-
TreeSet(Collection<? extends E> c):有参构造,传入一个集合,用集合初始化内置的map
-
TreeSet(SortedSet s):有参构造,传入一个SortedSet,用SortedSet初始化内置的map
10.3 一些API
都是封装的TreeSet的API,没什么可多说的
-
first()
:返回集合中第一个元素 -
last()
:返回集合中最后一个元素 -
lower(E e)
:返回集合比e小的元素 -
higher(E e)
:返回集合比e大的元素 -
floor(E e)
:返回集合小于等于e的元素 -
ceiling(E e)
:返回集合大于等于e的元素 -
subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
:返回从from到to的NavigableSet -
subSet(E fromElement, E toElement)
:返回从from到to的SortedSet -
tailSet(E fromElement)
:返回大于或等于from的SortedSet -
tailSet(E fromElement, boolean inclusive)
:返回大于(或等于当inclusive为true时)的NavigableSet -
headSet(E toElement)
:返回小于或等于to的SortedSet -
headSet(E toElement, boolean inclusive)
:返回小于(或等于当inclusive为true时)to的NavigableSet