2维对象包装器Java

时间:2013-07-27 18:27:07

标签: java

我想知道采用哪种方法来创建一个二维的“类数组”(或数组)泛型。

  1. 创建列表列表

    LinkedList<LinkedList<T>> myObject;
    
  2. 或者这种方法,更直观但需要使用Refecltion来检索类型。

    T[] testArray = c.cast(Array.
            newInstance(c.getComponentType(), dim1, dim2));
    
  3. 我的想法是我有一个包含成员变量的类:

    public class Board<T>
    {
        T[][] array;
    
        public Board(int vertical_size, int horizontal_size)
        {
            array = new T[vertical_size][horizontal_size]; //which is not allowed because of the way that java implements Generics
        }
    }
    

    我应该采取上面列出的两种方法中的哪一种..或者有更好的方法来解决这个问题吗?

5 个答案:

答案 0 :(得分:2)

您不需要T[][] - 您可以轻松使用Object[][](并在需要时转换为T)。如果您只允许T个实例填充数组,这应该没有问题。

事实上,如果您take a look,您会发现ArrayList<T>支持Object[](而不是T[])并使用类似方法:

111     private transient Object[] elementData;

...

336     @SuppressWarnings("unchecked")
337     E elementData(int index) {
338         return (E) elementData[index];
339     }

如果您不需要动态调整电路板大小,我认为这种方法比列表列表更有效。

答案 1 :(得分:1)

如果要创建类型安全的数组,只需执行以下操作即可。不知道每个人都有这样的想法你不能这样做:

import java.lang.reflect.Array;

public class Array2D<T> {
    private T[][] data;

    public Array2D(Class<T> clazz, int width, int height) {
        this.data = (T[][]) Array.newInstance(clazz, width, height);
    }

    public void putValue(int x, int y, T value) {
        data[x][y] = value;
    }

    public T getValue(int x, int y) {
        return data[x][y];
    }

    public static void main(String[] args) {
        Array2D<String> myStuff = new Array2D<String>(String.class, 10, 10);
        myStuff.putValue(3, 4, "Helloworld!");

        System.out.println(myStuff.getValue(3, 4));
    }
}

输出:

的Helloworld!

修改

如果您需要更高的性能,请考虑使用1D阵列并将其视为n维数组。这是使用Android设备时的一项已知改进,但前提是您不断访问该阵列。

此外,您可以强制调用者创建数组并完全避免使用反射。但是,除非您经常创建这些数组,否则它不会产生显着差异,尤其是当JVM优化调用时。

import java.lang.reflect.Array;

public class Array2D<T> {
    private T[] data;
    private final int height;
    private final int width;

    public Array2D(Class<T> clazz, int width, int height) {
        // Using 1D array instead of 2D array
        this((T[]) Array.newInstance(clazz, width * height), width, height); 
    }

    public Array2D(T[] data, int width, int height) {
        this.data = data;
        this.width = width;
        this.height = height;
    }

    public void putValue(int x, int y, T value) {
        data[x * width + y] = value;
    }

    public T getValue(int x, int y) {
        return data[x * width + y];
    }

    public static void main(String[] args) {
        Array2D<String> myStuff = new Array2D<String>(String.class, 10, 10);
        myStuff.putValue(3, 4, "Helloworld!");

        System.out.println(myStuff.getValue(3, 4));

        // Force the caller to create the array
        Array2D<String> myOtherStuff = new Array2D<String>(new String[5 * 10], 5, 10);
        myOtherStuff.putValue(2, 7, "Goodbyeworld!");

        System.out.println(myOtherStuff.getValue(2, 7));
    }
}

答案 2 :(得分:1)

这是我的想法(如果我理解了这个问题):

 class TwoDArray<T> {

    List<List<T>> list;

    public TwoDArray(int rows, int columns) {
    list = new ArrayList<List<T>>(rows);

    for(int i = 0; i<rows; i++) { 
        list.add(new ArrayList<T>(columns));
        for(int j = 0; j < columns; j++)
        list.get(i).add(j, null);
    }

    }

    public T getItem(int x, int y) {
    return list.get(x).get(y);
    }

    public void addItem(int x, int y, T e) {
    list.get(x).set(y, e);
    }

    public static void main(String[] args) {

    TwoDArray<String> bdimensional = new TwoDArray<String>(2, 2);
    bdimensional.addItem(1, 1, new String("hello"));
    bdimensional.addItem(0, 1, new String("bye"));  
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++)
        System.out.println( i + " " + j + ": " + bdimensional.getItem(i,j));
    }

    }

}

输出是:

0 0: null
0 1: bye
1 0: null
1 1: hello

我不知道为什么我的大脑确信(T) nullnCopies一起工作。 请查看Convenience Implementations

答案 3 :(得分:0)

首先,绝对没有办法尝试实现T[][]类型的2D数组。

我认为你自己已经用第一种类型回答了问题。但另一种有趣的方式(如果可能)将是:当您知道类型T将始终是另一种类型的子类型时。如果没有,则总是Object

interface SomeInterface{}

public class Board<T extends SomeInterface>
{
    SomeInterface[][] array;

    public Board(int horizontal_size, int vertical_size)
    {
        array = new SomeInterface[vertical_size][horizontal_size]; 
    }
}

然后您可以像使用2D数组一样使用array。虽然我仍然喜欢ArrayList<ArrayList<T>>

答案 4 :(得分:0)

有多种方法,但是既然你要包装实现,你可以简单地使用一个数组:

public class Board<T>
{
    private final Object[] array;
    private final int horizontal_size;

    public Board(int horizontal_size, int vertical_size)
    {
        array = new Object[vertical_size][horizontal_size];
        this.horizontal_size = horizontal_size;
    }

    // ...

    E get(int x, int y){
        // Check  if not out of bounds
        return (E) array[y * horizontal_size + x];
    }
}