hashcode来自字段的字符串concat与自动生成的方法

1bqhqjot  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(318)

如果我们有如下课程:

class ConnectedPair {
        private String source;
        private String destination;

        public ConnectedPair(String source, String destination) {
            if(source == null || destination == null) {  
                throw new NullPointerException();
            }
            this.source = source;
            this.destination = destination;
        }
}

我们想把它用在 HashMap 或者 HashSet 我们需要实施 equals 以及 hashCode 自动生成的 hashCode 本课程的目标是:

@Override
public int hashCode() {
    int result = source.hashCode();
    result = 31 * result + destination.hashCode();
    return result;
}

但我想知道我们是否应该做以下几点:

@Override
public int hashCode() {
    return (source + "=>" + destination).hashCode();
}

这比自动生成的方法好还是坏?正如我所看到的,其他脚本语言也在使用类似的方法,我想知道生成的哈希是更好还是更差(或者没有区别)。
注意:我们忽略字符串concat作为性能的缺点,假设它可以被缓存并因此得到优化

rxztt3cl

rxztt3cl1#

如果您所关心的只是一个有效的实现,并且对于意外和/或故意碰撞的可能性没有具体的要求,那么它们都是好的。这是大多数案件:你可以在这里停止调查。
这两个问题的定义都相当糟糕 String.hashCode() . 因为历史原因 String.hashCode() 对它的工作方式有一个固定的定义,这个定义是。。。糟糕。它很容易发生意外碰撞,并且很容易构造有意碰撞。
第二个(字符串连接)使得构造两个非常简单 ConnectedPair 具有相同哈希代码的对象( new ConnectedPair("a=>b", "c").hashCode() == new ConnectedPair("a","b=>c").hashCode() ). 另一个选项并不能完全阻止这一点,但会使构造样本稍微困难一些。
这听起来可能很愚蠢,但生成的代码是惯用的:每个看到这段代码的java开发人员都会很快理解您在做什么。您的“定制”实现似乎没有明显的问题,但是需要稍微多一些的脑力来解析。请记住:阅读代码的频率要比编写代码的频率高得多。

相关问题