无法使用 Set 删除重复的对号

Unable to use Set to remove duplicate pair numbers

假设我想在 8 x 6 网格上生成 20 个随机数。(8 列,6 行)。基于这里的回答:Creating random numbers with no duplicates,我这样写我的代码:

Random randomNumGenerator = new Random();
Set<Integer[][]> generated = new LinkedHashSet<Integer[][]>();
while (generated.size() < 20) {
    int randomRows = randomNumGenerator.nextInt(6);
    int randomColumns = randomNumGenerator.nextInt(8);
    generated.add(new Integer[][]{{randomRows,randomColumns}});
}

实际上发生的是 Set 看到 Integer[][]{{5,5}};Integer[][]{{5,5}}; 不是 duplicate.Why?即使我的目的是获得 20 个非重复的数字对,这也行不通。我该如何解决这个问题?

数组equals在Java中是==,所以一个数组只等于它自己。通常你使用 Arrays.equals(array1, array2) 来按内容比较它们,但在这种情况下,数组是完全错误的选择。您可以创建一个 bean,因为 rafalopez79 建议使用 Collections 数组(在您的情况下为 List),因为列表将比较 equals 上的内容,请参阅 documentation。完全由您选择,豆子可能更干净一些。

这段代码怎么样。我 运行 它通过调试器运行,它运行良好,是的,contains() 方法检查 Integer 的值,而不是引用。 运行dom号的运行ge可以根据需要更改,我这里为了方便测试使用了5。是的,我知道它不是很健壮,正如所写的那样,这将是一个无限循环(因为 运行ge 的限制为 5),但这是一个简单的例子来说明这一点。

更新:实际上这有一个错误,它不会检查所有行的唯一性,但这也很容易修复。我只是重新阅读了原始问题并查看了原始代码,我不确定我是否确切地知道您想要什么。如果您只想要一个包含 48 个独特 Intergers ar运行ged 8 x 6 的网格,这就可以了,但是有几种方法可以做到这一点。

    final int rows = 6;
    final int cols = 8;

    Random randomGenerator = new Random();


    ArrayList[] grid = new ArrayList[rows];

    for(int i=0; i<rows; i++)
    {
        grid[i] = new ArrayList<Integer>();

        for(int j=0; j<cols; j++)
        {
            for(;;)
            {
                Integer newInt = new Integer(randomGenerator.nextInt(5));               
                if(!grid[i].contains(newInt))
                {
                    grid[i].add(newInt);
                    break;
                }   
            }

        }
    }

Set 使用其内部类型的 equals 方法(以及 hashCode 方法)检查​​重复项,但 Integer[][]equals 方法比较内存地址而不是内容。

如果您只想存储对,为什么要使用 Set of Integer[][]? 不幸的是,在 Java 中没有 Pair class,但是如果您不想创建自己的,可以使用 Map.Entry

Random randomNumGenerator = new Random();
Set<Map.Entry<Integer, Integer>> generated = new LinkedHashSet<>();
while (generated.size() < 20) {
    int randomRows = randomNumGenerator.nextInt(6);
    int randomColumns = randomNumGenerator.nextInt(8);
    generated.add(new AbstractMap.SimpleEntry<>(randomRows,randomColumns));
}
System.out.println(generated);