【问题标题】:Generate unique key from List of int in Java从 Java 中的 int 列表生成唯一键
【发布时间】:2015-07-15 09:54:54
【问题描述】:

我有很多(不可变的)Integer 值列表。

其中一些包含完全相同的值。所以为了节省内存,我想找到那些。 出于这个原因,我使用HashMap<String, List<Integer>>

一种可行的方法是将值简单地连接到一个大的String 并将其用作HashMap 中的键。

这种方法工作可靠,但速度很慢,而且消耗大量内存。

我的 Integer 值介于 1 到 100,000,000 之间。这些列表包含 1 到 1000 个 Integer 值。

最多可以有 100,000,000 个列表。

我需要确保没有冲突。

【问题讨论】:

  • 假设您有两个列表,一个是1 -> 2 -> 3,另一个是2 -> 1 -> 3。两者都包含相同的数字,但如果我按顺序将每个数字连接到 String,我不会得到相同的结果。你是如何连接各种列表的,有什么顺序吗?
  • 在我看来,检查相等性比复制几个 List 要花费更多的精力。
  • 为什么不使用hashCode 作为映射键?
  • @rzysia:因为 hashCodes 不是碰撞安全的。
  • 由于pigeonhole principle,不可能为任意整数列表计算唯一短键(例如,intlong) .如果这是可能的,您将拥有一个出色的压缩算法 - 您可以将任意数量的数据压缩成一个小的、固定长度的代码……这显然是不可能的。

标签: java list key


【解决方案1】:
  • 将列表转换为BigInteger
  • Arrays.hashCode()List.hashCode(),视情况而定。
  • CRC32
  • SHA256、512、...

【讨论】:

  • 使用默认的 .hashCode() 方法不是碰撞安全的。你有建议如何实现碰撞安全吗?
  • No hashCode() 方法是碰撞安全的。你永远不会用那么多数据和那么大的范围来保证它的碰撞安全。您必须接受这是一个需要进一步测试相等性的哈希码。它仍然可以为您节省大量时间。
【解决方案2】:

您需要为您的收藏找到一些哈希函数。 我认为这个答案可能会对您有所帮助 - https://cstheory.stackexchange.com/questions/3390/is-there-a-hash-function-for-a-collection-i-e-multi-set-of-integers-that-has

【讨论】:

    【解决方案3】:

    尝试使用 Set。这是一个使用 Java8 的示例。它接受两个列表并创建一个单独的 Set,其中仅包含来自 list1 和 list2 的重复条目:

        Integer[] a = {1,2,2,3,1};
        List<Integer> list1 = Arrays.asList(a);
        List<Integer> list2 = Arrays.asList(a);
    
        Set<Integer> duplicates = list1.stream().filter(entry -> list2.contains(entry)).collect(Collectors.toSet());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多