(JAVA)HashSet里面保存的数据怎么变成有顺序的了?

weixin_38059994 2019-02-27 03:25:07
@tcxu 你好,想跟你请教个问题:

package jiu;
/**
 *@ClassName  HashSetDemo
 *
 * @Description 测试HashMapSet集合类
 *
 * @date  2014-3-3  上午8:45:26
 * 
 */

import java.util.HashSet;

public class HashSetDemo {
    public static void main(String args[]) {
        // 创建HashSet对象
        HashSet<String> hs = new HashSet<String>();
        // 加入元素到HastSet中
        hs.add("B");
        hs.add("A");
        hs.add("D");
        hs.add("E");
        hs.add("C");
        hs.add("F");
        System.out.println(hs);
    }
}



不是说HashSet是无序的吗?怎么输出结果却有序了?
...全文
795 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_46385780 2021-03-12
  • 打赏
  • 举报
回复
这里的有序是指,你输出的和输入的位置一样吧。无序就是输入的和输出的位置不相同
weixin_38117882 2019-03-04
  • 打赏
  • 举报
回复
我记得现在jdk8 版本的hashSet底层是调用HaseMap 的K来实现无序的,无序的概念并不是说你输入什么都会打乱顺序,他会按照HashCode进行插入到Hash 中,最后会用hash表存的顺序输出!
weixin_38104241 2019-03-01
  • 打赏
  • 举报
回复
你对无序这个概念有误差啊
weixin_38114857 2019-03-01
  • 打赏
  • 举报
回复
hashSet的无序是指不能以写入的顺序或倒序输出
weixin_38073737 2019-02-28
  • 打赏
  • 举报
回复
    hash 是无须的,或者说是不保证有序的。     但多次重新运行下列代码,亦可看出:每个 Integer 元素的哈希值,就是它的整形数的值。而且 hashset 的输出结果都是进行排序了的,那hashset 是怎么做到对结果的有顺序输出的呢? import java.util.HashSet;
import java.lang.Integer;
import java.util.Random;

public class SetOfInteger {
public static void main(String[] args) {
Random random=new Random(47);
HashSet<Integer> intset=new HashSet<Integer>();
for(int i=0;i<1000;i++){
int n = random.nextInt(50);
System.out.print( n + " hashCode: " + new Integer(n).hashCode() + ", ");
intset.add(n);
}
System.out.println("\n" + intset);
}
} 输出:     回答是: 虽然 hash 有它自己的顺序, 但这个顺序是hash的顺序.不一样的哈希算法,顺序也是不一样的。而且有序输出跟有序存储是两码事。     看来 正如 HashSet能对结果进行排序吗 的讨论指出的那样, "你需要百度下:数据结构、存储结构、还有hash键值对。总的来说你缺的太多,别一下直接想这么深的问题,先从数据结构开始学" 。
weixin_38096686 2019-02-28
  • 打赏
  • 举报
回复
试试下面的代码段: HashSet<String> hs = new HashSet<String>();
for (int i = 0; i < 26; i++) {
hs.clear();
hs.add(String.valueOf((char)('A' + i)));
hs.add(String.valueOf((char)('A' + 25 - i)));
System.out.println(hs.toString());
} 输出: [A, Z]
[B, Y]
[C, X]
[D, W]
[E, V]
[U, F]
[T, G]
[S, H]
[R, I]
[Q, J]
[P, K]
[L, O]
[M, N]
[M, N]
[L, O]
[P, K]
[Q, J]
[R, I]
[S, H]
[T, G]
[U, F]
[E, V]
[D, W]
[C, X]
[B, Y]
[A, Z]
[A, Z]  
weixin_38076769 2019-02-28
  • 打赏
  • 举报
回复
引用来自“wy65”的评论 可以把所有字母全部加入,然后在看看还是不是有序的 试了一下:将所有的单个大写、部分小写(a-g)、和部分数字字符(1-6), 作为长度为1的字符串,加起来。结果是"大写字符、小写字符、和 数字字符,分别升序排列输出"。只是数字的字符串最后出现。
import java.util.HashSet;

public class HashSetDemo_1 {
public static void main(String args[]) {
// 创建HashSet对象
HashSet<String> hs = new HashSet<String>();
// 加入元素到HastSet中
hs.add("3");
hs.add("6");
hs.add("5");
hs.add("4");
hs.add("2");
hs.add("1");

hs.add("b");
hs.add("g");
hs.add("d");
hs.add("e");
hs.add("c");
hs.add("f");

hs.add("B");
hs.add("A");
hs.add("D");
hs.add("E");
hs.add("C");
hs.add("F");
hs.add("X");
hs.add("Y");
hs.add("S");
hs.add("Z");
hs.add("T");
hs.add("V");
hs.add("U");
hs.add("J");
hs.add("I");
hs.add("K");
hs.add("I");
hs.add("M");
hs.add("L");
hs.add("A");
hs.add("Q");
hs.add("P");
hs.add("O");
hs.add("N");
hs.add("R");
hs.add("N");
hs.add("R");
hs.add("a");
hs.add("G");
hs.add("H");
System.out.println(hs);
}
}
weixin_38065106 2019-02-28
  • 打赏
  • 举报
回复
可以把所有字母全部加入,然后在看看还是不是有序的
weixin_38073649 2019-02-27
  • 打赏
  • 举报
回复
    是的,HashSet 元素的存储(地址)是无序的。一般来讲,通过进行迭代的迭代器也是依次将各个元素(字符串),无序地输出。     楼主所示的"有序结果",其实是一种极其特殊案例:每个元素都仅是一(单)个字符,或都是数字字符,或都是小写英文字符,或都是大写英文字符。     元素的存储地址,视这个元素的哈希值而定。由于元素仅有一个字符,其哈希值的计算结果,就会是这个给定字符的 ascii 码(参见: 哈希算法)的值。结果, 打印出的 HashSet 列表,就会是貌似经过排序后的结果。但要注意构成这种案例的条件:元素必须 都是单个数字字符、或都是单个英文小写字符、或都是单个英文大写字符。     下列代码显示每个元素的哈希值,以及最终调用 toString() 输出 HashSet hs 的结果。输出结果显示,单个字符元素的哈希值,就是它的 ASCII值。
import java.util.HashSet;

public class HashSetDemo {
static void showHashSet(String[] s){
HashSet<String> hs = new HashSet<String>();
for (int i=0;i<s.length;i++){
hs.add(s[i]);
System.out.println(s[i] + "的哈希值:" +s[i].hashCode()+ " ");
}
System.out.println("toString的结果:" + hs);
}
public static void main(String args[]) {
String data[][]=new String[5][6];
String dat[]={
"B","A","D","E","C","F", // 可以打印出貌似排序的结果
"6","4","3","1","2","5", // 可以打印出貌似排序的结果
"BB","AA","DD","EE","CC","FF",
"42","41","45","46","44","43",
"Base","Alberta","Done","End","Coding","Factory"};
for (int i=0;i<dat.length;i++)
data[i/6][i%6]=dat[i];
for (int i=0;i<data.length;i++)
showHashSet(data[i]);
}
} 输出:
B的哈希值:66
A的哈希值:65
D的哈希值:68
E的哈希值:69
C的哈希值:67
F的哈希值:70
toString的结果:[A, B, C, D, E, F]
6的哈希值:54
4的哈希值:52
3的哈希值:51
1的哈希值:49
2的哈希值:50
5的哈希值:53
toString的结果:[1, 2, 3, 4, 5, 6]
BB的哈希值:2112
AA的哈希值:2080
DD的哈希值:2176
EE的哈希值:2208
CC的哈希值:2144
FF的哈希值:2240
toString的结果:[BB, AA, DD, EE, CC, FF]
42的哈希值:1662
41的哈希值:1661
45的哈希值:1665
46的哈希值:1666
44的哈希值:1664
43的哈希值:1663
toString的结果:[44, 45, 46, 41, 42, 43]
Base的哈希值:2063089
Alberta的哈希值:743772625
Done的哈希值:2135970
End的哈希值:69819
Coding的哈希值:2023747466
Factory的哈希值:572770538
toString的结果:[Done, Alberta, Coding, Factory, End, Base]  
weixin_38069570 2019-02-27
  • 打赏
  • 举报
回复
HashSet的原理是:计算对象的hash值,并映射到数组的下标。再看一下String的hashCode()方法的源码 哈希值是通过char对应的int值计算出来的,即:char对应的int值越大,hash值就越大。 而在拉丁字母A、B、C、D的char字符对应的int值恰巧是递增的,所以他们的hash值也恰巧是递增的,所以最终映射到HashSet内的数组的位置也是顺序的。

477

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧