如何实现链接列表的二维数组

时间:2013-01-14 19:46:34

标签: java arrays generics collections

我正在努力从纸上实现算法。本文描述了使用网格,其中每个网格方块都包含一个整数的链接列表,表示该网格方块中的对象。

我决定使用LinkedList<Integer>[][]来实现这一点,这当然会给我一个generic array creation错误。

我想不出更好的方式来表示链接列表网格的概念。我也明白使用LinkedList[][]会编译,但这是不好的做法,因为它是无类型的。但是,我不想使用ArrayList<ArrayList<LinkedList<Integer>>>,因为这是不可读的,至少对我而言。

有没有办法在这里使用无类型的LinkedList?或许还有其他一些解决方案?

7 个答案:

答案 0 :(得分:5)

列表版本

List<List<List<Integer>>> grid;

不可读。要访问网格方块,只需

List<Integer> items = grid.get(x).get(y);

不是那么强硬。

答案 1 :(得分:2)

波西米亚人的回答是正确的。如果您使用的是Guava,则可能的替代方法是使用ArrayTable<Integer, Integer, List<Integer>>。来自文档:

  

由二维数组支持的固定大小Table实现。

     

表格必须提供允许的行和列键   创建。该表始终包含每个行键的映射/   列对。与给定行和列对应的值为null   除非提供另一个值。

     

表的大小是常数:提供的数量的乘积   行键和提供的列键数。删除和清除   表或其视图不支持方法。该   erase(java.lang.Object, java.lang.Object)eraseAll()方法可以   改为使用。

以下是其用法示例:

private static final int NUM_ROWS = 20; //for example
private static final int NUM_COLS = 20; //

private static final ArrayTable<Integer, Integer, List<Integer>> TABLE =
        ArrayTable.create(
                Ranges.closed(1, NUM_ROWS).asSet(DiscreteDomains.integers()),
                Ranges.closed(1, NUM_COLS).asSet(DiscreteDomains.integers())
        );

public static List<Integer> getGridQuareList(int row, int col) {
    @Nullable List<Integer> list = TABLE.at(row, col);
    if (list == null) {
        list = Lists.newArrayList(); //or newLinkedList() if you insist
        TABLE.set(row, col, list);
    }
    return list;
}

答案 2 :(得分:1)

我会使用嵌入式ArrayList / LinkedList。你可以做些什么来清理它,因为你知道它们将具有什么样的泛型类型,就是将它们包装在其他类中。像这样:

public class Grid {
    private List<List<List<Object>>> inner;

    public List<Object> objectsAtPosition(int x, int y) {
        return inner.get(x).get(y);
    }

    // etc
}

答案 3 :(得分:1)

我不知道为什么你需要一个3维列表(列表的2d数组,考虑到ArrayLists实际上是一个3d列表/数组)。但如果你需要,那么你应该使用@Bohemian所写的内容:

List<List<List<Integer>>> grid;

你应该考虑什么:

向接口声明变量,而不是实现,例如:

List<Integer> list = new ArrayList<Integer>

而不是

ArrayList<Integer> list = new ArrayList<Integer>

此外,通常将泛型与数组混合是不是一个好主意,它可能会变得令人讨厌。如果你不想在java中这样做,那就是你需要的java方式,正如其他人所说:

List<List<List<Integer>>>

答案 4 :(得分:1)

您可以按如下方式声明链接列表的数组..但是不要忘记在您打算使用链接列表时声明,否则您将获得nullpointeexception

    LinkedList<Integer>[][] ll = new LinkedList[24][24];
    ll[0][0] = new LinkedList<>();
    ll[0][0].addFirst(3);
    System.out.println(ll[0][0].removeFirst());

输出:3

答案 5 :(得分:0)

第一:你可以避免使用LinkedList。在算法书籍中,他们不知道ArrayList,Linked List,更像是动态列表的同义词 在几乎所有情况下,ArrayList都更快,特别是对于2D阵列,需要更少的内存。

我个人在拥有固定网格时,使用动态内容,我使用数组:

List grid[][];

// init with
grid = new ArrayList[numX][numY];

这样我有一个对象网格。这使用的内存要少得多。

这样,添加objetcs时会更加方便:

 List list = grid[i][j];
 if (list == null) {
      list = new ArrayList();
      this.cells[i][j] = list;
 }
 list.add(obj);

答案 6 :(得分:0)

  

我决定使用LinkedList [] []来实现它   当然会给我一个通用的数组创建错误。

     

我想不出更好的方式来表达网格的概念   链表。我也明白使用LinkedList [] []会   编译但是不好的做法,因为它是无类型的。

简单。要解决这些问题,请执行

LinkedList<Integer>[][] grid = (LinkedList<Integer>[][])new LinkedList<?>[5][3];