Java 字符串哈希集生成的输出不';不匹配字符串哈希函数

Java 字符串哈希集生成的输出不';不匹配字符串哈希函数,java,hashset,Java,Hashset,我正在准备一个UIL计算机竞赛,其中一个练习题涉及到一套,这里是逐字逐句: HashSet<String> set = new HashSet<String>(); set.add("000"); set.add("212"); set.add("211"); set.add("555"); set.add("343"); System.out.println(set); HashSet=newhashset(); 设置。添加(“000”); 设置。添加(“212”);

我正在准备一个UIL计算机竞赛,其中一个练习题涉及到一套,这里是逐字逐句:

HashSet<String> set = new HashSet<String>();
set.add("000");
set.add("212");
set.add("211");
set.add("555");
set.add("343");
System.out.println(set);
HashSet=newhashset();
设置。添加(“000”);
设置。添加(“212”);
设置。添加(“211”);
集合。添加(“555”);
集合。添加(“343”);
系统输出打印项次(套);
现在,我知道哈希集是未排序的数据结构,但显示了2个未排序的选项和1个排序的答案选项:

A) [00021134321555]

B) [00021121234355]

c) [000211555343212]

我天真地选择了B)排序后的答案,虽然正确的答案是A,但我仍然不明白为什么。我找到了由每个字符串的哈希函数生成的哈希代码:

“000”-47664

“212”-49619

“211”-49618

“555”-52629

“343”-50674


据我所知,哈希集使用哈希表作为其后端。在这种情况下,基于散列码,我不明白为什么答案是不正确的。我将代码插入java,它将生成正确答案选择的结果。这里发生了什么,HashSet到底是如何向自身添加项的?

因为支持数组可以小于hashcodes,所以顺序不仅取决于
hashcode()
,还取决于
hashcode()%arr.length。后备数组的默认大小为
16
,因此,如果您计算所列哈希代码的模,您将获得正确的顺序


对于具有相同哈希代码的元素,首先插入的也是第一个要打印的元素。这是因为bucket包含同一bucket中所有对象的列表(并使用
equals()
确定它们是否是同一个对象,或者它们是否恰好得到了同一个bucket)。

因为支持数组可以小于hashcode,所以顺序不仅仅由
hashcode()
确定,而是由
hashcode()确定%arr.length。后备数组的默认大小为
16
,因此,如果您计算所列哈希代码的模,您将获得正确的顺序

对于具有相同哈希代码的元素,首先插入的也是第一个要打印的元素。这是因为bucket包含同一bucket中所有对象的列表(并使用
equals()
确定它们是否是同一个对象,或者它们是否恰好得到了同一个bucket)。

A使用
HashMap
作为其支持数据:

这个类实现了
Set
接口,由一个哈希表(实际上是一个
HashMap
实例)支持

HashSet
使用
HashMap
快速确定元素是否已经存在

默认容量为
16

用默认初始容量(16)和默认负载系数(0.75)构造一个空的
HashMap

您已经添加了5项,几乎不足以满足负载系数乘以容量的要求,因此没有进行大小调整

您需要知道
HashMap
如何使用哈希代码来确定要使用哪个bucket。根据,Java做
hash&(SIZE-1)
只提取最低的n位,其中容量为2n

因此,铲斗编号如下所示:

“000”-47664->0

“212”-49619->3

“211”-49618->2

“555”-52629->5

“343”-50674->2

打印出集合使用一个迭代器
,该迭代器按顺序遍历存储桶。在同一个bucket中,使用插入顺序

因此,命令如下:

  • “000”-47664->0
  • “211”-49618->2
  • “343”-50674->2
  • “212”-49619->3
  • “555”-52629->5
  • 而与选项“A”匹配的则使用一个
    HashMap
    作为其支持数据:

    这个类实现了
    Set
    接口,由一个哈希表(实际上是一个
    HashMap
    实例)支持

    HashSet
    使用
    HashMap
    快速确定元素是否已经存在

    默认容量为
    16

    用默认初始容量(16)和默认负载系数(0.75)构造一个空的
    HashMap

    您已经添加了5项,几乎不足以满足负载系数乘以容量的要求,因此没有进行大小调整

    您需要知道
    HashMap
    如何使用哈希代码来确定要使用哪个bucket。根据,Java做
    hash&(SIZE-1)
    只提取最低的n位,其中容量为2n

    因此,铲斗编号如下所示:

    “000”-47664->0

    “212”-49619->3

    “211”-49618->2

    “555”-52629->5

    “343”-50674->2

    打印出集合使用一个迭代器
    ,该迭代器按顺序遍历存储桶。在同一个bucket中,使用插入顺序

    因此,命令如下:

  • “000”-47664->0
  • “211”-49618->2
  • “343”-50674->2
  • “212”-49619->3
  • “555”-52629->5
  • 这与选项“A”相匹配

    “212”-49619

    “211”-49618

    “555”-52629

    “343”-50674

    求每一个的mod除以16。然后分类。如果存在一个bucket匹配,那么最后添加的一个将首先出现在列表中(因为在发生冲突时它“作为堆栈实现”)

    “000”-47664

    “212”-49619

    “211”-49618

    “555”-52629

    “343”-50674

    求每一个的mod除以16。然后分类。如果存在一个bucket匹配,那么最后添加的一个将首先出现在列表中(因为在发生冲突时它“作为堆栈实现”)

    1)问题是错误的。根据

    它不保证集合的迭代顺序;特别是,它不能保证订单在一段时间内保持不变

    因为结果取决于简单程度