【问题标题】:Proper use of HashSet.contains()? [duplicate]正确使用 HashSet.contains()? [复制]
【发布时间】:2020-03-24 23:14:21
【问题描述】:

我正在尝试使用 Kruskal 算法的一个版本来生成迷宫。我需要检查某些坐标(在 int[] 数组中,例如 [1, 5])是否在现有集合中。

这里是部分代码的副本;

// find sets containing cells to be joined
for (HashSet<int[]> h : cells) {
    if (h.contains(new int[]{x, y - 2})) {
        set1 = h;
    }
}

问题在于 if 语句永远不会为真,但我 99.9% 的把握它至少应该为真一次。

我是否使用了 HashSet.contains() 错误?

谢谢

【问题讨论】:

    标签: java contains hashset


    【解决方案1】:

    认为这会有所帮助:

    Stream.generate(() -> new int[] { 1, 2 }.hashCode()).limit(3).forEach(System.out::println);
    

    请注意,我们将[1, 2] 的哈希码打印了三次,但我们得到了三个唯一值。那是因为每个new int[] 都有一个不同的hashCode()。创建一个自定义类型,覆盖 hashCode 并将 that 添加到您的 HashSet。类似的东西

    public class Cell {
        private final int x, y;
    
        public Cell(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public int getX() {
            return x;
        }
    
        public int getY() {
            return y;
        }
    
        @Override
        public int hashCode() {
            return 13 ^ x ^ y;
        }
    
        @Override
        public boolean equals(Object o) {
            if (o == null) {
                return false;
            } else if (this == o) {
                return true;
            } else if (o instanceof Cell) {
                Cell c = (Cell) o;
                return this.x == c.x && this.y == c.y;
            }
            return false;
        }
    }
    

    【讨论】:

    • 我建议使Cell(或Coordinate)类不可变。除此之外,在对象被添加到HashSet 之后以影响哈希码的方式对其进行变异将打破HashSet 的期望。
    【解决方案2】:

    我是否使用了 HashSet.contains() 错误?

    嗯,你有一个错误的期望,但它更多的是关于数组而不是HashSet。 Java 中的数组并没有像您期望的那样实现equalshashCode。它们有效地表现出参考平等行为。例如:

    int[] array1 = { 1 };
    int[] array2 = { 1 };
    System.out.println(array1.equals(array1)); // true - same reference
    System.out.println(array1.equals(array2)); // false - different reference
    

    与其使用int[] 作为坐标,我建议创建一个带有xy 字段的Coordinate 类。如果那个Coordinate 类然后适当地覆盖equalshashCode然后 使用HashSet 将起作用。 (虽然我建议您在循环之外而不是在每次迭代中创建您正在寻找的对象。)

    【讨论】:

      【解决方案3】:

      HashSet contains() Java 中的方法 实用程序。 HashSet contains() 方法用于检查 HashSet 中是否存在特定元素。所以基本上它用于检查 Set 是否包含任何特定元素。

      【讨论】:

      猜你喜欢
      • 2011-05-13
      • 1970-01-01
      • 2016-03-09
      • 2014-03-31
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      相关资源
      最近更新 更多