繁体   English   中英

Java:arraylists的二维数组?

[英]Java: 2D array of arraylists?

我正在开发数独解决方案,并且我需要一个9x9板上每个正方形的数字1到9的数组列表。 这些数组列表中的每一个对应于可能在那个正方形中出现的数字,如果一个数字不能在那个正方形中出现,则将其从列表中删除。

我希望能够提取正在处理的当前正方形的arraylist,例如,例如,如果我想从对应于square(3,5)的arraylist中删除数字7

arrayOfLists[3][5].remove(Integer.valueOf(7));

但是我不知道如何做到这一点。 当我尝试创建数组时,在声明数组列表数组的行上出现此错误

无法创建ArrayList的通用数组

这是我的代码:

    //create arraylist
    ArrayList<Integer> nums = new ArrayList<Integer>();

    //fill arraylist with numbers 1-9
    for (int i = 1; i < 10; i++) {
        nums.add(i);
    }

    //create 9x9 array of arraylists
    ArrayList<Integer>[][] array = new ArrayList<Integer>[9][9];

    //fill each element of array with arraylist of numbers 1-9
    for(int i = 0; i<9; i++){
        for(int j = 0; j<9; j++){
            array[i][j] = nums;
        }       
    }

}

我这样做有误还是无法创建arraylists数组? 如果不可能,那我该怎么办呢?

每当我看到列表列表时,警钟就会响起。 实际上,您真正想要这样的事情的情况确实很少见,而这并不是其中之一。

您有一个由9个固定的正方形,列和行组成的固定板,每个位置可能需要1-9的数字。

对所有这些概念都使用数组,因为它们的大小是固定的,并且您需要直接访问每个元素-集合没有好处,而且会成为一个障碍。 使用逻辑(可能是一组)来确保数字在每个区域中仅使用一次。

使用位字段而不是数组列表。 即,使用整数,其中位1-9代表数字的可能性。 测试,添加和删除单个数字是O(1),并且它具有固定的内存大小。 将整数封装在自己的知道操作的对象中。

一些东西:

1)在您的for循环中,array [i] [j] = nums; 这将在数​​组的每个元素中导致相同的对象。 如果在数组的一个元素上调用remove(),它将影响所有其他元素。 您要为每个元素构建一个单独的列表对象。

2)编程接口; 将nums声明为List,而不是ArrayList。

3)使用列表列表,而不是任何列表数组。

    List<List<List<Integer>>> list = new ArrayList<List<List<Integer>>>();
    for(int i = 0; i<9; i++){
        List<List<Integer>> row = new ArrayList<List<Integer>>();
        for(int j = 0; j<9; j++){
            List<Integer> nums = new ArrayList<Integer>();
            for (int k = 1; k < 10; k++) {
                nums.add(i);
            }
            row.add(nums);
        }
        list.add(row);
    }

    // You can still get an element by index
    int x = list.get(3).get(1).remove(6);

但这有点笨拙。 您可能需要考虑编写一个代表董事会的课程。 这样,您至少将拥有可以更好地对此进行抽象的操作。

您可以完全删除使用2d的内容,并通过为每个方块指定一个从1 ... 81开始的唯一编号来保留单个列表。 因此,如果您使用的是3,5单元格,则意味着它是列表中的9 * 2 + 5 = 23rd项。 这将大大简化列表操作。 给定(3,5)类型的引用,您可以使用一种方法来提供唯一的单元格索引

好的,我将其发布为答案,因为它似乎对我有用,而且我还没有发现任何陷阱。

private static class IntegerArrayList extends ArrayList<Integer> {
    IntegerArrayList () { super(); }
    IntegerArrayList (Collection<? extends Integer> c) { super(c); }
    IntegerArrayList (int initialCapacity) { super(initialCapacity); }
}

现在你可以说类似

IntegerArrayList[][] array = new IntegerArrayList[9][9];

并且诸如array [1] [2]之类的元素将继承所有ArrayList方法( array[1][2].remove(something)正常工作)。 我将类private static以为您可以在其他唯一的类中嵌套它,但是可以根据需要将其公开。 另外,我从ArrayList复制了所有三个构造函数; 您可以消除不需要的,但是我没有令人信服的理由。

我认为问题是禁止使用new ArrayList<Integer>[9][9] ,因为它会创建一个不会进行类型检查的数组(因为“类型擦除”)。 但是我认为添加您自己的从ArrayList<Integer>继承的非泛型类型可以恢复类型安全性。

但是我不是一般的专家,如果比我更有知识的人发现此解决方案有问题,也不会感到惊讶。 但这似乎对我来说很好用,没有编译器警告未检查的类型的东西。

(PS我将其发布为一个可能会引起很多问题的通用解决方案。但是实际上,对于这个特定问题,我可能只使用固定大小的布尔数组而不是ArrayList,就像其他数组一样,或者如果速度是一个真正的问题,我什至可以对整数进行位运算。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM