【问题标题】:good hashcode and equals implementation for a key having multiple integer values具有多个整数值的键的良好哈希码和等于实现
【发布时间】:2012-04-23 22:45:27
【问题描述】:

我的 hashmap 有这样的键:'2+4+5' , '653+65+1324+75'.(由 + 号分隔的整数值)

什么可能是一个好的哈希码和equals方法,以便像'2 + 4 + 5','5 + 4 + 2','4 + 5 + 2'这样的键......(2,4的所有排列,5) 应该返回相同的哈希码值,equals 应该返回 true。

我打算取键中的整数值,对它们进行排序,将它们按升序放入一个字符串中,然后调用该字符串的 hashcode 和 equals 方法。假设如果我有“5+2+4”,那么我会将其更改为“245”并调用字符串 hashcode 和 equals 方法。但这将是一项昂贵的操作,因为每次我都必须进行排序。并且 hashmap 中的所有方法,例如 put,get... 都会再次变得昂贵

有没有其他方法可以在对数或线性时间内做到这一点......

【问题讨论】:

  • 有一个“2+4+5”键似乎有点可疑——这真的是一个伪装的对象吗?如果是这样,写一个哈希码可能更自然。

标签: java algorithm


【解决方案1】:

一个好的哈希码算法应该针对输入的细微差异返回非常不同的哈希值。在您的情况下,您还认为值的排列是“相等的”。

似乎一个好的方法是解析组成整数,然后对它们进行排序(一种确保比较顺序一致的简单方法)然后:

如果两个值具有相同的排序组成数字,则认为它们相等。

使用经过验证的哈希方法,例如

hash = value1 + 31 * value2 + 31 * 31 * value3 + 31 * 31 * 31 * value4 + etc.

【讨论】:

    【解决方案2】:
    class Combination {
        final int[] parts;
    
        Combination(String str) {
            String[] strings = str.split("\\+");
            parts = new int[strings.length];
            for (int i = 0; i < parts.length; i++) {
                parts[i] = Integer.parseInt(strings[i]);
            }
            Arrays.sort(parts);
        }
    
        @Override public int hashCode() {
            return Arrays.hashCode(parts);
        }
    
        @Override public boolean equals(Object o) {
            return o instanceof Combination && Arrays.equals(parts, ((Combination) o).parts);
        }
    }
    

    测试代码:

    public static void main(String[] args) {
        Set<Combination> set = new HashSet<>();
        set.add(new Combination("1+2+3"));
        set.add(new Combination("1+2+4"));
        System.out.println(set.contains(new Combination("3+2+1"))); // prints "true"
        System.out.println(set.contains(new Combination("4+2+1"))); // prints "true"
        System.out.println(set.contains(new Combination("4+3+1"))); // prints "false"
    }
    

    【讨论】:

      【解决方案3】:

      简单而有效:

      public int hashcode(){
          int hash=5;
          for(int i:array)
             hash=hash*17+i;
      
          return hash;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-04
        • 1970-01-01
        • 2023-02-02
        • 2010-11-22
        相关资源
        最近更新 更多