3

我正在从一篇论文中实现一个算法。该论文描述了使用网格,其中每个网格正方形都包含一个整数链表,这些整数表示该网格正方形中的对象。

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

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

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

4

7 回答 7

5

列表版本

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

不是不可读的。要访问网格正方形,只需

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

对膜没那么难。

于 2013-01-14T19:55:07.017 回答
2

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

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

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

表的大小是恒定的:提供的行键的数量和提供的列键的数量的乘积。表或其视图不支持 remove 和 clear 方法。可以改为使用和 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;
}
于 2013-01-14T20:14:05.173 回答
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
}
于 2013-01-14T19:59:01.377 回答
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>>>
于 2013-01-14T20:04:56.950 回答
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

于 2016-12-12T17:25:50.893 回答
0

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

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

List grid[][];

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

这样我就有了一个对象网格。这使用更少的内存。

这样在添加对象时会更方便:

 List list = grid[i][j];
 if (list == null) {
      list = new ArrayList();
      this.cells[i][j] = list;
 }
 list.add(obj);
于 2013-01-14T19:52:10.267 回答
0

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

我想不出更好的方式来表示链表网格的概念。我也明白使用 LinkedList[][] 可以编译,但由于它是无类型的,所以这是不好的做法。

简单的。要解决这些问题,只需

LinkedList<Integer>[][] grid = (LinkedList<Integer>[][])new LinkedList<?>[5][3];
于 2013-01-15T00:52:24.460 回答