Java最高

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程

1.概述

在本文中,我们将探索TreeMap的实现地图接口从Java集合框架(JCF)。

TreeMap是一种映射实现,它按照键的自然顺序对条目进行排序,如果用户在构造时提供的话,最好还是使用比较器。

之前,我们已经讨论过HashMapLinkedHashMap实现,我们会意识到有很多关于这些类如何工作的信息是相似的。雷竞技app官网网站

在阅读这篇文章之前,强烈推荐阅读上面提到的文章。

2.默认排序TreeMap

默认情况下,TreeMap根据其自然顺序对所有条目进行排序。对于整数,这意味着升序,对于字符串,这意味着字母顺序。

让我们看看测试中的自然顺序:

@Test public void giventreemap_whenordersentriesnaturally_threct () {TreeMap map = new TreeMap<>();地图。把(3“val”);地图。把(2、“val”);地图。(1)“val”);地图。把(5“val”);地图。put(4, "val"); assertEquals("[1, 2, 3, 4, 5]", map.keySet().toString()); }

注意,我们以非有序的方式放置整数键,但是在检索键集时,我们确认它们确实是按升序维护的。这是整数的自然顺序。

同样,当我们使用字符串时,它们将按照自然顺序排序,即字母顺序:

@Test public void givenTreeMap_whenOrdersEntriesNaturally_thenCorrect2() {TreeMap map = new TreeMap<>();地图。把(“c”、“val”);地图。put (" b ",“val”);地图。把(“a”、“val”);地图。把(“e”,“val”);地图。put("d", "val"); assertEquals("[a, b, c, d, e]", map.keySet().toString()); }

TreeMap,不像散列映射和链接散列映射,它在任何地方都不使用散列原理,因为它不使用数组来存储条目。

3.自定义排序TreeMap

如果我们对自然排序不满意TreeMap,我们还可以在树形图的构造过程中通过比较器定义自己的排序规则。

在下面的例子中,我们希望整数键按降序排列:

@Test public void giventreemap_whenordersentriesbycomparator_threct () {TreeMap map = new TreeMap<>(Comparator.reverseOrder());地图。把(3“val”);地图。把(2、“val”);地图。(1)“val”);地图。把(5“val”);地图。put(4, "val"); assertEquals("[5, 4, 3, 2, 1]", map.keySet().toString()); }

哈希映射不保证存储的键的顺序,特别是不保证该顺序将随着时间保持不变,但树映射保证键将始终按照指定的顺序排序。

4.的重要性TreeMap排序

我们现在知道了TreeMap以有序的顺序存储它的所有条目。由于树映射的这个属性,我们可以执行以下查询:查找“最大”,“最小”,查找所有小于或大于某个值的键,等等。

下面的代码只涵盖了这些情况中的一小部分:

@Test public void giventreemap_whenperformsqueries_threcert () {TreeMap map = new TreeMap<>();地图。把(3“val”);地图。把(2、“val”);地图。(1)“val”);地图。把(5“val”);地图。put(4, "val"); Integer highestKey = map.lastKey(); Integer lowestKey = map.firstKey(); Set keysLessThan3 = map.headMap(3).keySet(); Set keysGreaterThanEqTo3 = map.tailMap(3).keySet(); assertEquals(new Integer(5), highestKey); assertEquals(new Integer(1), lowestKey); assertEquals("[1, 2]", keysLessThan3.toString()); assertEquals("[3, 4, 5]", keysGreaterThanEqTo3.toString()); }

5.的内部实现TreeMap

TreeMap实现了NavigableMap接口和基于其内部工作原理红黑树

public class TreeMap extends AbstractMap implements NavigableMap, Cloneable, java. io.com serializable

红黑树的原理超出了本文的范围,但是,为了理解它们是如何适用的,有一些关键的事情需要记住TreeMap

首先,红黑树是由节点组成的数据结构;想象一棵倒置的芒果树,它的根在天空中,树枝向下生长。根将包含添加到树中的第一个元素。

规则是,从根开始,任何节点的左分支中的任何元素总是小于该节点本身中的元素。右边的总是更大。定义大于或小于是由元素的自然顺序或我们前面看到的构造时定义的比较器决定的。

该规则保证树映射的条目总是按有序和可预测的顺序排列。

其次,红黑树是一种自平衡二叉搜索树。这个属性和上述属性保证了搜索、获取、放置和删除等基本操作所花费的时间为对数O (log n)

自我平衡是关键。当我们不断插入和删除条目时,想象树的一边长一些,另一边短一些。

这意味着操作在较短的分支上花费的时间更短,而在离根最远的分支上花费的时间更长,这是我们不希望发生的。

因此,在红黑树的设计中要考虑到这一点。对于每次插入和删除,树在任何边缘上的最大高度保持为O (log n)也就是说,树木不断地平衡自己。

就像哈希映射和链接哈希映射一样,树映射不是同步的,因此在多线程环境中使用它的规则与其他两个映射实现中的规则相似。

6.选择正确的地图

在看着HashMapLinkedHashMap以前和现在的实现TreeMap,重要的是要在三者之间做一个简短的比较,以指导我们哪一个适合哪里。

一个散列映射作为提供快速存储和检索操作的通用映射实现很好。然而,它的不足,因为它的混乱和无序排列的条目。

这导致它在有很多迭代的情况下性能很差,因为底层数组的整个容量影响遍历,而不仅仅是条目的数量。

链接散列映射拥有哈希映射的良好属性,并向条目添加顺序。在迭代次数较多的地方,它的性能更好,因为只考虑条目的数量而不考虑容量。

树图通过提供对键应该如何排序的完全控制,将排序提升到下一个级别。另一方面,它提供比其他两种选择更差的总体性能。

我们可以说a链接哈希映射减少了哈希映射排序的混乱,而不会导致树映射的性能损失

7.结论

在本文中,我们探索了JavaTreeMap类及其内部实现。由于它是一系列通用Map接口实现中的最后一个,我们还将简要讨论它与其他两种接口实现的最佳关系。

本文中使用的所有示例的完整源代码可以在GitHub项目

Java底部

开始使用Spring 5和Spring Boot 2,通过学习的春天课程:

>>看看这个课程
对这篇文章的评论关闭!