社区
Java SE
帖子详情
不是说hashset对元素的存储是无序的吗?那为什么输出是有序的?
五维浪人
2019-10-15 03:16:59
...全文
614
6
打赏
收藏
不是说hashset对元素的存储是无序的吗?那为什么输出是有序的?
[图片]
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
6 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
yuyishui
2019-10-16
打赏
举报
回复
无序指的是你遍历时不保证输出的顺序=输入的顺序 换String输入试试看
编程写手
2019-10-16
打赏
举报
回复
你使用的是int类型,本身哈希值就是数值,然后结果就是有序的
阿发你好
2019-10-15
打赏
举报
回复
无序的意思不保证顺序。。
maradona1984
2019-10-15
打赏
举报
回复
Integer的hashCode就是数字本身,HashSet其实用的是HashMap的实现,下标是根据hashCode算出来的 (h = key.hashCode()) ^ (h >>> 16),低于2的16次方的数字hash的结果还是自身,你的测试只能说明你的数字太小
yety123
2019-10-15
打赏
举报
回复
https://blog.csdn.net/qq_24251323/article/details/52748398 参考博文
烫炒栗子
2019-10-15
打赏
举报
回复
import java.util.HashSet; public class HashTableTest { public static void main(String[] args) { HashSet<Integer> set = new HashSet<Integer>(); for (int i = 1; i < 12; i++) { set.add(i); } set.add(17); System.out.println(set); System.out.println(hash(17)); } /* set.add()方法其实在底层最终是调用了一个hash方法,此方法是对数据的hashcode进行处理,然后返回一个整数,这个数最终就是在set集合中存储的位置 */ static final int hash(Object key) { //此方法对数据的hashcode进行处理 int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } } 运行结果为: [1, 17, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 17 通过上面的代码可以看出,set 的存储确实是无序的,那么为什么楼主的30个数字全都是有序输出呢,我们可以根据set的存储原理来分析一下。 首先要知道Hash表是由数组和链表来进行数据存储的,默认情况下数组长度是16(这个长度是动态变化的),当里面的数据超过阈值的时候(当前数组的0.75倍),数组就会自动的增加或减少(增加或减少的数值为2的倍数) import java.util.HashSet; public class HashTableTest { public static void main(String[] args) { // HashSet<Integer> set = new HashSet<Integer>(); // for (int i = 0; i < 11; i++) { // set.add(i); // } // set.add(17); // System.out.println(set); // System.out.println(hash(17)); for(int i = 1; i<12;i++){ System.out.print(hash(i) + ","); } System.out.print(hash(17)); } static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } } 运行结果为: 1,2,3,4,5,6,7,8,9,10,11,12,17 首先我先输出一下这12个数字经过hash方法处理过的结果,这就是每个数字所对应的最终在内部存储的位置,首先添加第一个数据1,那么这个数字和hash方法处理过返回的数字相同,那么底层就用这个1%16(数组默认为16)得到的余数为1,那么就会将1存进索引为1的数组中,,同理类推2就会存入索引为2的数组中,那么到了17的时候得到的余数为1,就会存入到索引为1的数组中。如图1所示: 那么当我们继续往里面添加一个数字12的时候(代码在下面),经过hash方法的计算,整数12的这个返回值也是12,(其实10000以前的数值包括后面的一些整数返回来的值都是本身,当你查询99999的时候返回值就不是本身了)那么我们前面说过当数据超过阈值的时候(默认值16*0.75 = 12)数组就会增加2的倍数变为32,此时数据在集合内部的存入位置就会发生改变。如下图2所示: 那么当set遍历的时候就会从索引1的位置开始遍历一直到最后的17结束,这里的17是因为数组的长度发生了变化,从16变为32,所以17%32的余数为17,位置就发生了变化 import java.util.HashSet; public class HashTableTest { public static void main(String[] args) { HashSet<Integer> set = new HashSet<Integer>(); for (int i = 1; i < 13; i++) { set.add(i); } set.add(17); System.out.println(set); System.out.println(hash(17)); // for(int i = 1; i<13;i++){ // System.out.print(hash(i) + ","); // } // System.out.print(hash(17)); } static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } } 运行结果为: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17] 17 此时数组长度为32,32*0.75=24,也就是说当我们从1添加到24的时候,他的输出顺序都是有序的 运行结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] 当你在往里面继续添加数字25的时候数组的长度又超过阈值,此时数组长度会自动变为128,128*0.75=96那么这时候你往里面存入1-96的时候输出是都是按照顺序输出的。可自行测试。
详解Java中
HashSet
和TreeSet的区别
当向
HashSet
集合中存入一个
元素
时,
HashSet
会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值来决定该对象在
HashSet
中的
存储
位置。简单地
说
,
HashSet
集合判断两个
元素
相等的...
【194期】
HashSet
是
无序
的吗?为什么
输出
的结果
有序
?
点击上方“Java精选”,选择“设为星标”别问别人为什么,多问自己凭什么!下方有惊喜,留言必回,有问必答!每天08:15更新文章,每天进步一点点...什么是集合?集合简称集,是数学中一...
Java-为什么遍历
输出
HashSet
是
有序
的?
Java遍历
HashSet
为什么
输出
是
有序
的?*Java集合中
有序
无序
的概念一、问题起因二、过程三、总结 *Java集合中
有序
无序
的概念 首先先了解清楚Java集合中
有序
无序
的概念, 有助于更好的理解
HashSet
为什么
输出
是
有序
的!...
Java遍历
HashSet
为什么
输出
是
有序
的?
HashSet
是否
无序
来源:知乎BWH.Steven Java 技术公众号:理想二旬不止 ...我们一般
说
HashSet
是
无序
的,它既不能保证
存储
和取出顺序一致,更不能保证自然顺序(a-z) 下面是《Thinking ...
为什么
HashSet
输出
是
有序
的?
HashSet
的迭代器在
输出
时“不保证
有序
”,但也不是“保证
无序
”。也就是
说
,
输出
时
有序
也是允许的。当
元素
比较多时,会是
无序
的概率大些。
Java SE
62,635
社区成员
307,269
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章