java有序不重复的集合 Java遍历HashSet时,为什么输出是有序的?
Java遍历HashSet时,为什么输出是有序的?首先,上面是hash的类描述,表示hash可以是无序的,也可以是有序的。问一下会是什么样子,让我们看看HashSet的源代码实现。HashSet的底层
Java遍历HashSet时,为什么输出是有序的?
首先,上面是hash的类描述,表示hash可以是无序的,也可以是有序的。问一下会是什么样子,让我们看看HashSet的源代码实现。
HashSet的底层由具有空键的HashMap存储。
HashMap的数据结构是table[entry],这是一个链表结构,每个数据元素都是一个链表。具有相同hashcode的不同键将落在表[hashcode]的链表上。
但是当HashMap存储值时,它将根据密钥的hashcode()计算存储位置(该位置是散列的,所以它是无序的);
它感觉是有序的,因为hashcode()不重复。如果不要求ID是数字,建议使用最简单的一个,即UUID,它包括机器代码、时间戳、随机数等,但UUID最终生成一个全局唯一的字符串,而不是整数,并且看起来顺序不对。
2. MySQL自己添加ID。它使用一个表来存储各种业务id。每个分布式系统插入一个ID后,生成1000万个本地号码与ID拼接,然后每个系统得到一个ID,相当于生成1000万个ID,足够长时间使用。这1000万个ID可以预先定义,并在系统启动时放入内存。因为它们只是ID,所以不会占用太多内存。MySQL可以内置到集群中,这不会影响自增IDs的使用。
3. 与MySQL的auto-increment ID类似,redis的incr实现了自动增量。每个分布式系统,比如redis,都是用incr插入一个ID,然后生成1000万个本地号码与ID拼接,如果每个系统都有一个ID,相当于生成1000万个ID,足够长时间使用。这1000万个ID可以预先定义,并在系统启动时放入内存。因为它只是一个ID,所以不会占用太多内存。Redis也可以内置到集群中,这不会影响自增ID的使用。Twitter的雪花算法与UUID类似,包括机器码、时间戳、随机数等,但最终生成的是64位整数,可以满足许多分布式系统的要求。如果Id必须是整数,建议使用snowflake而不是UUID。
javaWeb 在系统高并发的情况下生成有序流水号?
1. Linkedhashset继承自hahsset。构造方法使用三个参数调用方法。构造方法的底层初始化LinkedHashMap。因为LinkedHashMap是有序的,所以linkedhashset也是有序的。为什么我们不能调用这个构造函数?它是包访问级别,不能在外部调用。接下来,分析LinkedHashMap是如何实现的,以理解为什么它是有序的。
2. 先看下面的图片。(对于写在手机上的问题,你不能把图片放在文字里,它们都在下面。)。
LinkedHashMap的数据结构与HashMap不同。HashMap中的条目有四个属性:key、value、hash和next,而LinkedHashMap中的条目添加了before和after属性。因此,LinkedHashMap在HashMap的基础上使用双向链表来连接所有节点。当然,它也有一个头部节点,所以遍历可以有序进行。具体结构如图所示。
3. LinkedHashMap主要重写addentry和createentry方法,在创建节点时创建双向链表。
此外,LinkedHashMap还可以实现LRU算法的缓存。
源代码基于JDK7查看ha。如果你不懂HashMap,你可以看到我分享的另一篇文章。
希望对您有所帮助,您可以关注我,以后会分享更多的架构和java知识文章。