Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可变对象的hashCode()是否有用途?_Java_Hash_Hashcode - Fatal编程技术网

Java 可变对象的hashCode()是否有用途?

Java 可变对象的hashCode()是否有用途?,java,hash,hashcode,Java,Hash,Hashcode,我一直在浏览Java集合框架的源代码,注意到AbstractList和AbstractMap将其元素的哈希代码之和作为自己的哈希代码值返回。这使得列表和映射实现根据集合的内容返回不同的哈希代码值 我知道的hashCode()方法的唯一用途是将元素均匀地分布到使用散列的数据结构内部的存储桶中,例如HashSet和HashMap。但是,Set和Map合同规定: 当对象是集合中的元素时,如果对象的值以影响相等比较的方式更改,则不会指定集合的行为 以及: 如果对象是贴图中的关键点时,对象的值以影响相等比

我一直在浏览Java集合框架的源代码,注意到
AbstractList
AbstractMap
将其元素的哈希代码之和作为自己的哈希代码值返回。这使得列表和映射实现根据集合的内容返回不同的哈希代码值

我知道的
hashCode()
方法的唯一用途是将元素均匀地分布到使用散列的数据结构内部的存储桶中,例如
HashSet
HashMap
。但是,
Set
Map
合同规定:

当对象是集合中的元素时,如果对象的值以影响相等比较的方式更改,则不会指定集合的行为

以及:

如果对象是贴图中的关键点时,对象的值以影响相等比较的方式更改,则不会指定贴图的行为

这些契约使得可能根据其状态返回不同散列值的对象在集合中使用和在映射中用作键时非常危险。这让我想知道:

  • 返回变量散列值有意义吗
  • 返回一个常量(每个对象类)散列值不是更好吗
  • hashCode()
    方法除了在散列集合中使用之外还有什么用处
  • 返回变量散列值有意义吗

    数据结构不知道是否更改了键或元素的哈希代码。这样做会损坏数据结构。但是,如果在将对象添加到散列集合之前对其进行了变异,但之后没有对其进行更改,则这将起作用

    返回一个常量散列值不是更好吗

    是的,但该常量必须与equals一致,在这种情况下,返回常量的唯一方法是不改变用于创建hashCode()的任何字段

    hashCode()方法除了在哈希集合中使用之外还有什么用途

    它可以用于识别用于调试/记录目的的单个对象,但如果您使用的是内置对象.hashCode()或System.identityHashCode(),它会更有用。这是一种快速检查两个对象是否为同一参考的方法

    ByteBuffer bb = ByteBuffer.allocate(1024);
    ByteBuffer bb2 = ByteBuffer.allocate(1024);
    
    useBB(bb);
    useBB(bb2);
    
    public static void useBB(ByteBuffer bb) {
        System.out.println(Thread.currentThread()+" - Using bb " + System.identityHashCode(bb));
        // do something
    }
    
    如果您看到两个线程使用相同的ByteBuffer,您可能会遇到问题

    您可以在实例化时在构造函数中生成它,就像它对字符串对象所做的那样

    String的hashCode是按需生成的,以减少在不需要hashCode的地方创建字符串的开销。注意:除非有人试图创建哈希代码为0的字符串,否则拥有哈希代码为0的字符串虽然很少见,但代价很高

    类似地,对象的hashCode也是按需生成的。它存储在Oracle/OpenJDK的标头中,未设置的初始值为0,但第一次使用时设置为1-2^31-1

    此程序通过将hashCode重置为0,对
    Object.hashCode()
    的成本进行基准测试

    该程序使用更简单的策略对Object.HashCode()的设置进行基准测试

    我的意思是,您需要根据最终字段生成它,所以哈希值不会改变

    这还不足以保证哈希代码不发生变化,例如

    class A {
        final List<String> strings = new ArrayList<>();
    
        public int hashCode() {
            return strings.hashCode();
        }
    }
    
    A类{
    最终列表字符串=新的ArrayList();
    公共int hashCode(){
    返回字符串。hashCode();
    }
    }
    
    您的字段必须是
    final
    且不可变。以确保哈希代码不会更改。然而,如果你不改变它们,它们也不会改变

  • 返回变量散列值有意义吗
  • 不可以。但是,如果用户在将列表用作哈希表中的键时小心不修改列表及其内容,则哈希值不会改变,哈希表操作将正常工作。这当然是危险的,因为用户有责任确保哈希代码在需要时不会更改,但这是可能的

  • 返回一个常量散列值不是更好吗
  • 不是真的。确实,它保证哈希代码值始终遵守其约定(两个相等的对象始终返回相同的哈希代码),即使列表发生更改。。。但是,如果由于一个常量哈希代码,所有元素都放在同一个bucket中,那么使用哈希表又有什么意义呢?性能将非常糟糕,最好在此时使用另一种集合类型

  • hashCode()方法除了在哈希集合中使用之外还有什么用途
  • 没有别的了。有些人创造性地使用了hashcode值,但它们通常是无效的,并且基于对hashcode含义的错误理解

    返回变量散列值有意义吗

    对。类的
    hashCode()
    方法应该与其
    equals()
    方法一致。如果一个类根据可变状态定义实例相等,那么它的
    hashCode()
    也应该根据相同的可变状态定义

    这样的对象很少适合包含在基于散列的集合中,但如果小心避免在它们留在集合中时对它们进行变异,则可以在这样的集合中使用它们

    返回一个常量散列值不是更好吗

    Object.hashCode()
    事实上就是这样,假设您在每个实例的意义上指的是“常量”。如果您不重写
    equals()
    ,那么也没有很好的理由重写该常量散列值,但是如果您重写
    equals()
    ,那么您确实应该提供一致的
    hashCode()
    实现

    hashCode()方法除了在哈希集合中使用之外还有什么用途

    如果一个类缓存了它计算出的散列码,那么比较实例的散列码可以作为一种廉价的“可能相等”测试,允许绕过更昂贵的exac