TreeMap 自定义排序的几种使用方法

1.使用键的自然排序

如果键实现了 Comparable 接口,那么 TreeMap 会使用键的自然排序。例如,如果你的键是 IntegerString 类型,那么不需要额外的配置。

// 使用 Integer 的自然排序
TreeMap<Integer, String> map = new TreeMap<>();
map.put(3, "three");
map.put(1, "one");
map.put(2, "two");

System.out.println(map);  // 输出 {1=one, 2=two, 3=three}

2. 通过实现 Comparable 排序

如果键是自定义类型,你可以让该类型实现 Comparable 接口,并重写 compareTo 方法来定义键之间的比较逻辑。

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);  // 按年龄排序
    }

    @Override
    public String toString() {
        return name + ":" + age;
    }
}

// 使用 Person 的自然排序
TreeMap<Person, String> personMap = new TreeMap<>();
personMap.put(new Person("Alice", 25), "A");
personMap.put(new Person("Bob", 20), "B");
personMap.put(new Person("Charlie", 30), "C");

System.out.println(personMap);  // 输出 {Bob:20=A, Alice:25=B, Charlie:30=C}

3. 使用自定义 Comparator 排序

你还可以通过提供一个 Comparator 实例来定义键之间的比较逻辑。

// 使用自定义 Comparator 按年龄排序
TreeMap<Person, String> personMap2 = new TreeMap<>(new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        return Integer.compare(p1.age, p2.age);
    }
});

personMap2.put(new Person("Alice", 25), "A");
personMap2.put(new Person("Bob", 20), "B");
personMap2.put(new Person("Charlie", 30), "C");

System.out.println(personMap2);  // 输出 {Bob:20=A, Alice:25=B, Charlie:30=C}

4. 使用 Lambda 表达式简化 Comparator

从 Java 8 开始,可以使用 Lambda 表达式来简化 Comparator 的定义。

// 使用 Lambda 表达式
TreeMap<Person, String> personMap3 = new TreeMap<>(Comparator.comparingInt(Person::getAge));

personMap3.put(new Person("Alice", 25), "A");
personMap3.put(new Person("Bob", 20), "B");
personMap3.put(new Person("Charlie", 30), "C");

System.out.println(personMap3);  // 输出 {Bob:20=A, Alice:25=B, Charlie:30=C}

5. 使用方法引用来进一步简化

如果你使用的 Comparator 只是比较对象的一个属性,可以使用方法引用来进一步简化代码。

// 使用方法引用
TreeMap<Person, String> personMap4 = new TreeMap<>(Comparator.comparing(Person::getAge));

personMap4.put(new Person("Alice", 25), "A");
personMap4.put(new Person("Bob", 20), "B");
personMap4.put(new Person("Charlie", 30), "C");

System.out.println(personMap4);  // 输出 {Bob:20=A, Alice:25=B, Charlie:30=C}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Treemap 是一种基于红黑树(Red-Black Tree)数据结构的有序映射(Sorted Map)实现。它的底层实现原理主要包括以下几点: 1. 红黑树:Treemap 使用红黑树作为内部数据结构来存储键值对。红黑树是一种自平衡二叉搜索树,通过对节点进行染色和旋转操作来维持树的平衡性和有序性。 2. 键值对排序Treemap 中的键值对按照键的自然排序或者自定义排序规则进行排序。红黑树的特性使得插入、删除和查找操作的时间复杂度为 O(log n),因此 Treemap 可以高效地支持有序映射的操作。 3. 节点存储:Treemap 的每个节点都包含一个键和一个值。通过比较键的大小,节点按照有序性被插入到红黑树中的合适位置。在每个节点中,左子节点的键小于当前节点的键,右子节点的键大于当前节点的键。 4. 平衡性维护:为了维持红黑树的平衡性,Treemap 使用了红黑树的特性:每个节点都被标记为红色或黑色,同时满足以下几个约束条件: - 根节点是黑色的。 - 所有叶子节点(NIL 节点)是黑色的。 - 如果一个节点是红色的,则它的两个子节点都是黑色的。 - 从任意节点到其每个叶子节点的路径上,黑色节点的数量相同。 通过保持这些约束条件,Treemap 可以保持树的平衡性,从而保证了插入、删除和查找操作的时间复杂度始终为 O(log n)。 需要注意的是,Treemap 不允许键为 null,同时它不是线程安全的,如果需要在多线程环境下使用,可以考虑使用 ConcurrentNavigableMap 接口的实现类,例如 ConcurrentSkipListMap。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值