JDK 7的算法和数据结构

在定期检查JDK中是否存在一种或另一种标准算法时,我决定进行这种索引。 有趣的是,为什么其中包含一些著名的数据结构或算法,而另一些却没有? 此调查的格式仅涉及JDK的算法和数据结构的关键特性和功能,所有详细信息和完整描述-您可以在javadoc或jdk源代码中轻松找到。 让我们从简单开始到复杂!

JDK的数据结构

jdk中有一个堆栈 ,它是从堆栈中出现的-类Stack ,但不建议使用它,它很复杂又很奇怪:它继承自Vector ,因此基于Dynamic Array并已同步。 为什么一个简单的栈需要这一切,为什么它不只是一个接口-目前尚不清楚(讨论过很多次: 1 , 2 ),但似乎只是一个架构的错误,同样与载体本身。 顺便说一句,JDK作者自己建议使用Deque 。

Deque – 双端队列的接口(api)(O中的LIFO + FIFO(1)),其中包括堆栈操作(push,pop,isEmpty,size),并且到目前为止在jdk中可用(1.6+) 。 当然,将这些堆栈操作放在接口Stack中会更合乎逻辑,例如让Deque继承它,但是由于Stack已经存在,并且向后兼容性是Java的“圣杯” –他们不得不牺牲常规设计。 Deque的实现是ArrayDeque和LinkedList ,它们也是常规队列的实现者–因此我们将在后面讨论。

队列

接下来,让我们看一下队列数据类型 。 这里的一切都很好,设计得很好。 队列 – FIFO队列的接口(api),以恒定时间O(1)添加到开头并从结尾删除。

主要实现有: ArrayDeque ,基于动态可扩展数组的循环缓冲区 (填充时加倍)和LinkedList ( 经典的双向链接列表) (大小不受限制)。 令人惊讶的是,第一个不支持随机访问 (使用索引添加/删除/获取),第二个却支持O(n)时间并通过链表进行迭代。 这些类还实现了上述Deque,因此它们支持从末尾移除并在恒定时间内添加到顶部。

接下来,从jdk 1.5+开始,添加了PriorityQueue ,这实际上违反了合同,因为队列元素不是从末尾检索的(并且也不添加到头部),而是根据优先级检索的。 PriorityQueue基于可扩展的二进制堆 ,其顶部最小(根据其比较器),并且在填充时提高了1.5倍。 关键特征分别是:元素的添加/删除在O(log N)中,而对最小值(标头)的引用在O(1)中。

其他类型的队列是为多线程使用而设计的,它们是: BlockingQueue , TransferQueue , ConcurrentLinkedQueue和ConcurrentLinkedDeque 。

BlockingQueue ( ArrayBlockingQueue , LinkedBlockingQueue , PriorityBlockingQueue )的实现是其原始版本的一种同步版本,即几乎每个操作都是串行执行的(具有独占锁定)。 对于DelayQueue也是如此:也是同步的,并且在内部使用PriorityQueue 。

其他实现: SynchronousQueue , TransferQueue ( LinkedTransferQueue ), ConcurrentLinkedQueue , ConcurrentLinkedDeque –基于不同的方法:它们使用基于链表和CAS指令的非阻塞队列算法,这些算法在多处理器环境中可以很好地并行化。 详细描述在源代码中。

这类算法的理论是一个非常庞大且现代的话题,因此还没有很好的标准化和结构化,它们超出了本文的讨论范围,也不属于另一篇文章的主题。

优先队列

就像从jdk 1.5+开始所说的那样,有一个通用的PriorityQueue根据元素比较器工作。 而且,jdk中还有堆的另一种实现。 这是很好的旧Timer ,它是内部类– TaskQueue(顶部的延迟最小的任务)。 当然,这是一个私有类,除了在Timer内部,不能使用。

清单

如您所知,有顺序和/或随机访问类型列表。 在Java中,它是List ,主要有2种实现:首先-是ArrayList ,支持随机访问 ,基于动态可扩展数组 (填充时增加一半),但是在删除所有元素后不会缩小,您需要调用a特殊方法( trimToSize )。

第二个-再次是LinkedList,它是一个双链表顺序访问大小,仅受jvm的内存限制。 尽管也存在随机访问(索引)的方法–如前所述,它们需要O(n)时间。

因此,java集合中没有最简单的链表实现,尽管这是一个好主意(链接的开销减少了2倍),并且没有简单的堆栈。

要在多线程环境中使用列表,有几个选项: CopyOnWriteArrayList (更改操作– O(n)),包装器( synchonizedList )以及过时的Vector 。

符号表

它们在JDK中显示为二进制树和哈希表。 二叉树 –它是TreeMap (或TreeSet ), SortedMap (也是SortedSet)的实现,它基于经典的红黑树 ,即是平衡的,并且对于O(log N)保证了其基本操作,并且不限大小。 jdk中不存在其他类型的树。

哈希表是HashMap (也是HashSet ),它可能是Java中最常用的结构,它基于可动态扩展的哈希表,具有与链表的单独链接 ,具有所有功能:性能取决于哈希函数的质量,因此最坏的情况是O(N)。 当大小达到预定的loadFactor时, HashMap的大小将增加一倍。 值得注意的是,为了保护错误的哈希函数,使用了双哈希,并且对调用hashCode()的结果应用了棘手的位算法。

在JDK中,也有带有开放地址(线性探测)的哈希表实现。 其中之一是IdentityHashMap ,当键和值都存储在彼此相邻的同一数组中时,它会使用经典线性探测的优化版本,以实现更好的数据缓存(javadoc:«大型表的局部性比使用单独的数组»)

第二种开放寻址实现是非常特定的:它仅用于存储ThreadLocal元素( ThreadLocalMap中的内部隐藏类),当然不可用。

还有多线程版本: ConcurrentHashMap中 ,包装synchronizedMap , 哈希表和ConcurrentSkipListMap 。 包装器-自然只是阻止了常规HashMap Hashtable的版本-同一件事(并且是旧的,不建议使用), ConcurrentHashMap-锁条版本,减少了关键的锁部分(最好阅读JCiP ,这里是( 摘录 ) ConcurrentSkipListMap –是哈希表的非阻塞命名算法的改编版本(有关详细信息,请参见源代码)。

集合(不包含重复项)–在Java中设置 ,并通过HashMap实现,因此所有被称为哈希表的对象–对HashSet有效。

图表

图结构和算法未在jdk中表示。 因此,您只能为此使用第三方库。

弦乐

java中通常有一个字符串实现:基于unicode字符数组。 值得一提的是,从1.7_17版本开始,由于已复制子字符串,因此子字符串的性能为O(n)。

有趣的是, 此实现使用了一种简单的(强力)子字符串搜索算法,该算法在最坏的情况下以O(N * M)运行,并且没有一些有效的算法(在有限状态机上构建:Knuth-Morris-Pratt等) 。

原因有几个:字母UTF字符大(〜65K),因此存储状态机的开销很大,而就采用了蛮力算法(不使用额外的内存)。 其次,在平均输入字符串上–根据统计数据,该算法与其他算法相比并没有很多。

与排序相同:有有效的基数排序字符串algs(LSD,MSD等),但是在jdk中,有一个用于字符串的标准对象排序 ,如果运行,则以O(M * N * log N)运行大部分线相差不大(M –线长)。 原因是相同的:快速计数字符串算法需要额外的UTF字母大小的数组,这使得它们在平均输入上非常无效。

JDK算法

排序

由于jdk7发生了许多有关各种选项的更改,因此讨论了很多次,关于此主题的信息和文章很多,您可以轻松地将其搜索出来。

简而言之,这是jdk中排序实现的实际列表: TimSort –默认情况下对对象进行排序; mergesort –还用于对象;旧版本(通过系统属性启用); Dual-Pivot Quick sort –用于基元;然后按计数排序用于字节/字符数组,最后插入排序用于任何情况下使用的小数组。

集合内容使用Collections.sort(List…)进行排序,仍然可以通过将集合复制到数组中,对其进行排序,然后相应地覆盖集合内容来完成。 因此,尽管没有开销,对集合进行排序仍然是不可能的,尽管我认为拥有就地排序的链表是一个好主意。 Java中的字符串排序也使用对象版本完成,原因已经提到。

正在搜寻

对于原语和对象的所有数组以及随机访问列表实现(例如ArrayList等),都存在传统的二进制搜索 。 此外,JDK中还有一个二进制搜索链接列表的版本! 令人惊讶的是:JDK没有对链表进行排序,但是对它们进行二进制搜索! 尽管没有太大意义,因为这种版本的性能为O(N)。

常用表达

为此提供了Pattern和Matcher类。 Java使用基于带回溯的非确定性有限状态机( NFA )的传统实现。 因此,在退化的输入上,在最坏的情况下它给出了指数复杂度 O(m ^ N),例如,在Java中运行此regexp并尝试添加/删除“ a”符号:“ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aa )* b”)

此外,还有所谓的有序交替-此功能可在找到第一个匹配项后停止搜索,但不会显示最具体(最长)的搜索结果( 例如 )。

哈希函数,校验和

jdk中有hashCode实现的六个版本,并且Park-Miller_random_number_generator是默认版本,其他很简单,例如常量或对象内存地址,并且不使用算法,您可以在c ++ jdk源代码中找到它们。 MessageDigest类中还有行业标准的哈希算法(SHA-*,MD5和变体)。

对于校验和,有Adler-32 ( javadoc )和CRC32 ( javadoc )算法的实现。

压缩

jdk中有一个标准的压缩deflate( Deflater )算法的实现,并且zip / gzip jdk utils使用它。 它们都在java.util.zip包中 。

摘要

如您所见,经典数据结构并未完全用Java呈现,但与此同时,几乎所有jdk中的所有数据结构都可以使用很多线程安全版本。 缺少的是一个悬而未决的问题。 例如,您可以争辩jdk是否需要一些Union-Find,但是在社交网络时代完全缺少该语言的图形结构和算法非常令人惊讶,并且实际上会产生许多错误和自行车。

参考:来自我们JCG合作伙伴 Mikhail Baturov 的JDK 7的算法和数据结构,这是另一个俄罗斯编程人员.blog博客。

翻译自: https://www.javacodegeeks.com/2013/07/algorithms-and-data-structures-of-jdk-7.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在本地运行查看github上的开源项目

看中了一款很多星星的github的项目,想把这个项目拉到自己的电脑上运行查看项目效果,该怎么做?示例:我们今天要看的 github项目地址:https://github.com/lzxb/vue-cnode1.克隆项目: git clone [https://gith…

box-shadow技巧分享

box-shadow box-shadow在定义里是这么说的:"box-shadow 属性向框添加一个或多个阴影。" 是的,和他的名字一样,这个属性固然是用来制造阴影效果让页面更有立体感的。 语法: box-shadow: h-shadow v-shadow blur sprea…

puppet enc mysql_精通Puppet配置管理工具

目  录第1章 开始使用Puppet11.1 什么是Puppet11.1.1 部署21.1.2 配置语言和资源抽象层31.1.3 事务层51.2 选择正确的Puppet版本51.3 我能混用Puppet的版本吗61.4 安装Puppet71.4.1 在Red Hat企业版Linux和Fedora上面安装Puppet71.4.2 在Debian和Ubuntu上安装Puppe…

Web测试实践——每日例会记录12.31(1)

姓名 主要负责部分 完成情况 储志峰 刘伟清 阶段一,软件评测。对华科软院和计院的网站展开对比分析,主要体现在功能、界面等方面。描述网站的缺陷。 √ 吕尚维 阶段二,用户调研。对使用华科软院网站的某个用户展开调研,采访…

Spring JPA数据+休眠+ MySQL + Maven

在Spring MVC的帮助下开发Web应用程序意味着要创建几个逻辑架构层。 层之一是DAO(存储库)层。 它负责与数据库进行通信。 如果您至少开发了DAO层一次,则应该知道它涉及许多样板代码。 Spring Data本身就是与DAO相关的日常工作的一部分。 在帖…

关于DJANGO MODELS的个人理解和RELATED_NAME的使用

转自:http://www.cnblogs.com/blogofwyl/p/4283513.html作为一个新人(刚刚大学还没有毕业就出来实习,可以说是真的什么都不知到,什么都要重新学,但是这样真的可以锻炼自己的意志力和能力)。现在在公司是前端和后端一起坐&#xff…

HTML的入门概念

超文本<a> 文本或图像都可以用作链接的标签。使用“..”可以连接到源文件的上层文件夹。“..”表示“父文件夹”。 <a href"目标网址#锚点" name"页面锚点名称" title"鼠标滑过显示的文本">链接显示的文本</a> <a href&…

PDF之pdfkit

说起pdf就想到了一款很适用的工具&#xff0c;那就是pdfkit&#xff0c;在前几天的项目中&#xff0c;有一个功能要实现&#xff0c;为了实现这一个功能&#xff0c;于是我大海茫茫中查询各种百科&#xff0c;不负众望的让我找到了我心怡的工具&#xff0c;想必也就是它了。好了…

015迭代器

注意迭代器和可迭代对象不同#迭代器&#xff1a;1、有iter方法&#xff0c;2、有next方法li[1,2,3,4,5]diter(li) # 等于li.__iter__()print(d) # <list_iteratorobjectat0x00000174316CC3C8>可以通过next方法取出元素。for循环就是这样的。for循环内部做的三件事1、调用…

CSS属性之attr()

attr()准确的说&#xff0c;不应该是一个属性&#xff0c;而是一个CSS的函数&#xff0c;我们先看看MDN上的介绍吧&#xff1a; Summary The attr() CSS function is used to retrieve the value of an attribute of the selected element and use it in the style sheet. It c…

番石榴15 –新功能

本月初发布了新版本的Guava库&#xff0c;其中包含一些新功能和改进。 以下是此版本中一些重要的API新增功能的概述&#xff1a; 1.逃脱者 Escapers使您可以“转义”字符串中的特殊字符&#xff0c;以使字符串符合特定格式。 例如&#xff0c;在XML中&#xff0c;必须将<字…

MySQL大小写敏感的解决方案

前言&#xff1a;对于MySQL的大小写敏感的影响&#xff0c;笔者在一个小项目中深刻的体会到&#xff1a;当想要查询一条数据时&#xff0c;总是出来两条或多条&#xff0c;后来发现是大小写敏感造成的原因&#xff0c;本文就该问题提出解决方案。 1.MySQL大小写敏感的控制 mysq…

java主类型_Java主类结构:基本数据类型

Java语言是面向对象设计的语言&#xff0c;java车光绪的基本组成单元是类&#xff0c;类体中有包括属性与方法两部分。每一个应用程序都需要main()方法&#xff0c;含有main()方法的类成为主类建立一个java首先要建立包package Number;//建立的package包名为numberpuublic clas…

day3-文件操作之打开模式

r 只能读 r 可读可写&#xff0c;不会创建不存在的文件。如果直接写文件&#xff0c;则从顶部开始写&#xff0c;覆盖之前此位置的内容&#xff0c;如果先读后写&#xff0c;则会在文件最后追加内容。 w 只能写 覆盖整个文件 不存在则创建 w 可读可写 如果文件存在 则覆…

利用border制作三角形原理

网站前端页面中&#xff0c;有时候会使用一些三角形&#xff0c;除了使用图片的方式之外&#xff0c;利用css的border属性也可以做出相对应的三角形。那么&#xff0c;利用border是如何实现三角形的制作的呢&#xff1f; 先看下面一个例子&#xff1a; CSS代码&#xff1a; w…

Java开发中的常见危险信号

在开发&#xff0c;阅读&#xff0c;复审和维护成千上万行Java代码的几年中&#xff0c;我已经习惯于看到Java代码中的某些“ 危险信号 ”&#xff0c;这些信号通常&#xff08;但可能并非总是&#xff09;暗示着代码问题。 我不是在谈论总是错误的做法&#xff0c;而是在有限的…

js判断对象数组中是否存在某个对象

1. 如果要判断数组中是否存在某个元素的话很好判断&#xff0c;直接用数组的indexOf方法就好&#xff0c;存在返回当前索引不存在返回-1 var arr[1,2,3,4] arr.indexOf(3) // 2 arr.indexOf(5) // -1 2. 要只是判断的话是可以遍历后判断对象的属性是否相同的&#xff0c;像这种…

java weblogic 配置_java----weblogic部署应用

安装略创建域在部署过程中&#xff0c;不能用回退按钮&#xff0c;如果输入有误的话只能在该步设置完后重复进行设置。Linux命令和文件(夹)名是区分大小写的。1、进入weblogic的bin目录&#xff1a;#以具体安装目录为准cd /weblogic/Oracle/Middleware/Oracle_Home/wlserver/co…

sass 基础——回顾

1.webstorm 自动编译SASS  下载安装包 http://rubyinstaller.org/downloads/  然后点击安装&#xff0c;路径为默认路径就行&#xff0c; 勾选以下两项    add Ruby executables to your PATH    Associate .rb and rbw files with this Ruby information  安装完…

这么多年第一次自己去用游标和临时表

汗颜&#xff0c;做了这么多年开发自己第一次用游标和临时表 还是借助度娘才写出来的&#xff0c;请大家给指点下。。。 1 CREATE PROCEDURE [dbo].[sp_LaodDefaultFM]2 (3 ExhID int ,4 DefaultExhID INT,5 Result INT6 )7 AS 8 BEGIN 9 --判断当前会话中临时表是…