Как создать универсальный массив в Java? - PullRequest
994 голосов
/ 09 февраля 2009

Из-за реализации обобщений Java вы не можете иметь такой код:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

Как я могу реализовать это, поддерживая безопасность типов?

Я видел решение на форумах Java, которое выглядит следующим образом:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

Но я действительно не понимаю, что происходит.

Ответы [ 29 ]

0 голосов
/ 28 июня 2017

Я на самом деле нашел довольно уникальное решение, чтобы обойти невозможность инициировать универсальный массив. То, что вам нужно сделать, это создать класс, который принимает переменную общего типа T следующим образом:

class GenericInvoker <T> {
    T variable;
    public GenericInvoker(T variable){
        this.variable = variable;
    }
}

и затем в вашем классе массива просто начните так:

GenericInvoker<T>[] array;
public MyArray(){
    array = new GenericInvoker[];
}

запуск new Generic Invoker[] вызовет проблему с непроверенным, но на самом деле не должно быть никаких проблем.

Чтобы получить из массива, вы должны вызвать массив [i] .variable следующим образом:

public T get(int index){
    return array[index].variable;
}

Остальное, например, изменение размера массива, можно сделать с помощью Arrays.copyOf (), например, так:

public void resize(int newSize){
    array = Arrays.copyOf(array, newSize);
}

И функцию добавления можно добавить так:

public boolean add(T element){
    // the variable size below is equal to how many times the add function has been called 
    // and is used to keep track of where to put the next variable in the array
    arrays[size] = new GenericInvoker(element);
    size++;
}
0 голосов
/ 13 февраля 2011

попробуйте это.

private int m = 0;
private int n = 0;
private Element<T>[][] elements = null;

public MatrixData(int m, int n)
{
    this.m = m;
    this.n = n;

    this.elements = new Element[m][n];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            this.elements[i][j] = new Element<T>();
        }
    }
}
0 голосов
/ 05 апреля 2012

Простой, хотя и грязный, обходной путь к этому заключался бы во вложении второго класса-держателя в ваш основной класс и использовании его для хранения ваших данных.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}
0 голосов
/ 03 июня 2015
private E a[];
private int size;

public GenSet(int elem)
{
    size = elem;
    a = (E[]) new E[size];
}
0 голосов
/ 15 сентября 2014

Вы можете использовать приведение:

public class GenSet<Item> {
    private Item[] a;

    public GenSet(int s) {
        a = (Item[]) new Object[s];
    }
}
0 голосов
/ 09 июля 2014

Мне интересно, будет ли этот код создавать эффективный универсальный массив?

public T [] createArray(int desiredSize){
    ArrayList<T> builder = new ArrayList<T>();
    for(int x=0;x<desiredSize;x++){
        builder.add(null);
    }
    return builder.toArray(zeroArray());
}

//zeroArray should, in theory, create a zero-sized array of T
//when it is not given any parameters.

private T [] zeroArray(T... i){
    return i;
}

Редактировать: Возможно, альтернативным способом создания такого массива, если требуемый размер был известен и мал, было бы просто ввести требуемое количество нулей в команду zeroArray?

Хотя, очевидно, это не так универсально, как использование кода createArray.

0 голосов
/ 09 февраля 2009

Вы можете создать массив объектов и привести его к E везде. Да, это не очень чистый способ сделать это, но он должен хотя бы работать.

0 голосов
/ 19 апреля 2018

Создание общего массива запрещено в Java, но вы можете сделать это как

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}
0 голосов
/ 21 августа 2013

Возможно, не имеет отношения к этому вопросу, но пока я получал ошибку "generic array creation" при использовании

Tuple<Long,String>[] tupleArray = new Tuple<Long,String>[10];

Я нахожу следующие работы (и работал на меня) с @SuppressWarnings({"unchecked"}):

 Tuple<Long, String>[] tupleArray = new Tuple[10];
...