当前位置: 首页 > 知识库问答 >
问题:

直接使用哈希代码访问哈希集?(爪哇)

牟飞沉
2023-03-14

嗨,我想知道如果你有你要寻找的对象的Hashcode,是否可以直接访问HashSet的内容,有点像在HashMap中使用Hashcode作为键。

我想它可能会像这样工作:

MyObject object1 = new MyObject(1); 

Set<MyObject> MyHashSet = new HashSet<MyObject>();

MyHashSet.add(object1)

int hash = object1.getHashCode

MyObject object2 = MyHashSet[hash]???

谢谢

编辑:谢谢你的回答。好的,我知道我可能会稍微推动HashSet的契约,但是对于这个特定的项目,等式完全由hashcode决定,我确信每个hashcode/hashbucket只有一个对象。我非常不愿意使用HashMap的原因是,我需要将映射的基本整数转换为整数对象,因为HashMap只接受对象作为键,而且我还担心这可能会影响性能。我还能做些什么来实现类似的功能吗?

共有3个答案

武睿
2023-03-14

这是不可能的,因为HashSet是一个对象,并且没有公共API。此外,多个对象可以具有相同的哈希代码,但对象可以不同。

最后,使用myArray只能访问数组[

海岳
2023-03-14

HashSet由一个HashMap提供内部支持,对于这个问题,该HashMap无法通过公共API获得。但是,我们可以使用反射来访问内部映射,然后找到具有相同的hashCode的键:

private static <E> E getFromHashCode(final int hashcode, HashSet<E> set) throws Exception {
    // reflection stuff
    Field field = set.getClass().getDeclaredField("map");
    field.setAccessible(true);

    // get the internal map
    @SuppressWarnings("unchecked")
    Map<E, Object> interalMap = (Map<E, Object>) (field.get(set));

    // attempt to find a key with an identical hashcode
    for (E elem : interalMap.keySet()) {
        if (elem.hashCode() == hashcode) return elem;
    }
    return null;
}

在示例中使用:

HashSet<String> set = new HashSet<>();
set.add("foo"); set.add("bar"); set.add("qux");

int hashcode = "qux".hashCode();

System.out.println(getFromHashCode(hashcode, set));

输出:

qux
柯昱
2023-03-14

HashSet的常见实现得到了HashMap的支持(相当懒惰),因此您避免HashMap的努力可能会失败。

基于过早优化是万恶之源,我建议您首先使用HashMap,如果intInteger和从Integer的装箱/拆箱开销真的是一个问题,您必须实现(或找到)一个手工制作的HashSet,使用primitiveints进行比较。标准Java库确实不想考虑装箱/拆箱成本。很早以前,整个语言就在简单性方面获得了相当大的收益。请注意,这些天(从2004年开始!)这种语言会自动装箱和拆箱,这表明“你不必担心这个”策略。在大多数情况下,这是正确的。

我不知道你的HashKeyedSet需要有多“丰富”,但一个基本的哈希表其实并不难。

 类似资料:
  • 每个人在建构 PHP 应用时终究都会加入用户登录的模块。用户的帐号及密码会被储存在数据库中,在登录时用来验证用户。 在存储密码前正确的 哈希密码 是非常重要的。密码的哈希操作是单向不可逆的,该哈希值是一段固定长度的字符串且无法逆向推算出原始密码。这就代表你可以哈希另一串密码,来比较两者是否是同一个密码,但又无需知道原始的密码。如果你不将密码哈希,那么当未授权的第三者进入你的数据库时,所有用户的帐号

  • 问题内容: 我有一个实现了hashCode()的向量类。它不是我写的,而是使用2个质数对2个向量分量进行异或运算。这里是: …因为这是来自已建立的Java库,所以我知道它可以正常工作。 然后,我有一个Boundary类,其中包含2个向量:“开始”和“结束”(代表直线的端点)。这两个向量的值是边界的特征。 在这里,我尝试为构成该边界的向量的唯一2元组(起点和终点)创建一个良好的hashCode()。

  • 哈希是键/值对 如果你想按名字查询,那么需要哈希。哈希的键必须唯一,但值可以是任意标量。 有时候你仍然会看到人们称它为“关联数组”,但不要想当然的把它作为数组。 通过键/值对列表来创建哈希 使用键/值对列表创建哈希: my %stooges = ( 'Moe', 'Howard', 'Larry', 'Fine', 'Curly', 'Howard', 'Iggy'

  • Swift 4集合是用于存储相同类型的不同值,但它们没有像数组那样的有明确排序顺序。 如果不需要元素排序,或者需要没有重复值(唯一值),则可以使用集合而不是数组(集合只允许不同的值)。 类型必须是可散列类型并且是可以比较的,才能存储在一个集合中。哈希值是对象的值相等。例如,如果两个对象相等:,则。 默认情况下,所有基本值都是可散列类型,可以用作集合值。 创建集 使用以下初始化语法创建某个类型的空集

  • 在许多Redis教程中(比如本教程),数据存储在一个集合中,但多个值组合在一个字符串中(即,用户帐户可以作为两个条目“user:1000:username”和“user:1000:password”存储在集合中)。 然而,Redis也有哈希。似乎拥有一个“user:1000”散列会更有意义,它包含一个“username”条目和一个“password”条目。您只需直接在哈希中访问它们,而不是连接字符

  • 我刚刚讨论了散列码的概念,遇到了一行: