¿Cómo crear una matriz genérica en Java?


Debido a la implementación de Java generics, no puede tener código como este:

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

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

¿Cómo puedo implementar esto manteniendo la seguridad de tipo?

Vi una solución en los foros de Java que dice así:

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;
}

Pero realmente no entiendo lo que está pasando.

Author: Cœur, 2009-02-09

29 answers

Tengo que hacer una pregunta a cambio: ¿está su GenSet "marcado" o "sin marcar"? ¿Qué significa eso?

  • Comprobado: escritura fuerte . GenSet sabe explícitamente qué tipo de objetos contiene (es decir, su constructor fue llamado explícitamente con un argumento Class<E>, y los métodos lanzarán una excepción cuando se les pase argumentos que no sean de tipo E. Véase Collections.checkedCollection.

    -> en ese caso, usted debe escribe:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • Sin control: tipificación débil . No se realiza ninguna comprobación de tipo en ninguno de los objetos pasados como argumento.

    -> en ese caso, debe escribir

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

    Tenga en cuenta que el tipo de componente de la matriz debe ser el borrado del parámetro tipo:

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

Todo esto resulta de una debilidad conocida y deliberada de los genéricos en Java: se implementó usando borrado, por lo que " genérico" las clases no saben con qué argumento de tipo se crearon en tiempo de ejecución, y por lo tanto no pueden proporcionar seguridad de tipo a menos que se implemente algún mecanismo explícito (comprobación de tipo).

 593
Author: Varkhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-06 04:19:53

Siempre puedes hacer esto:

E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];

Esta es una de las formas sugeridas de implementar una colección genérica en Java Efectiva; Ítem 26. No hay errores de tipo, no hay necesidad de emitir la matriz repetidamente. Sin embargo esto desencadena una advertencia porque es potencialmente peligroso, y debe usarse con precaución. Como se detalla en los comentarios, este Object[] ahora se disfraza como nuestro tipo E[], y puede causar errores inesperados o ClassCastExceptionsi se usa de forma insegura.

Como regla general, este comportamiento es seguro siempre y cuando el array cast se use internamente (por ejemplo, para respaldar una estructura de datos), y no se devuelva ni se exponga al código del cliente. Si necesita devolver un array de tipo genérico a otro código, la clase reflection Array que menciona es el camino correcto.


Vale la pena mencionar que siempre que sea posible, tendrá un tiempo mucho más feliz trabajando con List s en lugar de matrices si está utilizando genéricos. Ciertamente a veces usted no tiene una opción, pero el uso de la collections framework es mucho más robusto.

 167
Author: dimo414,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-31 00:12:32

Aquí está cómo usar genéricos para obtener una matriz de exactamente el tipo que está buscando mientras preserva la seguridad de tipos (a diferencia de las otras respuestas, que le devolverán una matriz Object o darán como resultado advertencias en tiempo de compilación):

import java.lang.reflect.Array;  

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

    public GenSet(Class<E[]> clazz, int length) {  
        a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));  
    }  

    public static void main(String[] args) {  
        GenSet<String> foo = new GenSet<String>(String[].class, 1);  
        String[] bar = foo.a;  
        foo.a[0] = "xyzzy";  
        String baz = foo.a[0];  
    }  
}

Que compila sin advertencias, y como se puede ver en main, para cualquier tipo de declarar una instancia de GenSet como puede asignar a a una matriz de ese tipo, y puede asignar un elemento de a a una variable de ese tipo, lo que significa que la matriz y los valores en la matriz son del tipo correcto.

Funciona mediante el uso de literales de clase como tokens de tipo de tiempo de ejecución, como se explica en los tutoriales de Java . Los literales de clase son tratados por el compilador como instancias de java.lang.Class. Para usar una, simplemente siga el nombre de una clase con .class. Así, String.class actúa como un objeto Class que representa la clase String. Esto también funciona para interfaces, enumeraciones, matrices de cualquier dimensión (por ejemplo, String[].class), primitivas (por ejemplo, int.class), y palabra clave void (es decir, void.class).

Class en sí mismo es genérico (declarado como Class<T>, donde T significa el tipo que el objeto Class está representando), lo que significa que el tipo de String.class es Class<String>.

Por lo tanto, cada vez que llame al constructor para GenSet, pase un literal de clase para el primer argumento que representa una matriz del tipo declarado de la instancia GenSet (por ejemplo, String[].class para GenSet<String>). Tenga en cuenta que no podrá obtener una matriz de primitivas, ya que las primitivas no se pueden usar para variables de tipo.

Dentro del constructor, llamando al método cast devuelve el argumento Object pasado fundido a la clase representada por el objeto Class en el que se llamó al método. Llamar al método estático newInstance en java.lang.reflect.Array devuelve como Object un array del tipo representado por el objeto Class pasado como primer argumento y de la longitud especificada por el int pasado como segundo argumento. Llamar al método getComponentType devuelve un objeto Class que representa el componente tipo de la matriz representada por el objeto Class en el que se llamó al método (por ejemplo, String.class para String[].class, null si el objeto Class no representa un array).

Esa última frase no es del todo exacta. Llamar a String[].class.getComponentType() devuelve un objeto Class que representa la clase String, pero su tipo es Class<?>, no Class<String>, por lo que no se puede hacer algo como lo siguiente.

String foo = String[].class.getComponentType().cast("bar"); // won't compile

Lo mismo ocurre con cada método en Class que devuelve un objeto Class.

Respecto El comentario de Joachim Sauer sobre esta respuesta (no tengo suficiente reputación para comentar sobre ella yo mismo), el ejemplo usando el cast a T[] dará lugar a una advertencia porque el compilador no puede garantizar la seguridad de tipos en ese caso.


Editar con respecto a los comentarios de Ingo:

public static <T> T[] newArray(Class<T[]> type, int size) {
   return type.cast(Array.newInstance(type.getComponentType(), size));
}
 56
Author: gdejohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:45

Esta es la única respuesta que es type safe

E[] a;

a = newArray(size);

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}
 34
Author: irreputable,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-06 04:11:51

Para extender a más dimensiones, simplemente agregue []'s y parámetros de dimensión a newInstance() (T es un parámetro de tipo, cls es un Class<T>, d1 a través de d5 son enteros):

T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

Véase Array.newInstance() para más detalles.

 27
Author: Jason C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-12 18:55:29

En Java 8, podemos hacer una especie de creación de matriz genérica usando una lambda o referencia de método. Esto es similar al enfoque reflexivo (que pasa a Class), pero aquí no estamos usando la reflexión.

@FunctionalInterface
interface ArraySupplier<E> {
    E[] get(int length);
}

class GenericSet<E> {
    private final ArraySupplier<E> supplier;
    private E[] array;

    GenericSet(ArraySupplier<E> supplier) {
        this.supplier = supplier;
        this.array    = supplier.get(10);
    }

    public static void main(String[] args) {
        GenericSet<String> ofString =
            new GenericSet<>(String[]::new);
        GenericSet<Double> ofDouble =
            new GenericSet<>(Double[]::new);
    }
}

Por ejemplo, esto es usado por <A> A[] Stream.toArray(IntFunction<A[]>).

Esto podría también hacerse antes de Java 8 usando clases anónimas, pero es más engorroso.

 11
Author: Radiodef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-05 01:17:05

Esto está cubierto en el Capítulo 5 (Genéricos) de Java Efectivo, 2a Edición, ítem 25... Prefieren listas a matrices

Su código funcionará, aunque generará una advertencia sin marcar (que podría suprimir con la siguiente anotación:

@SuppressWarnings({"unchecked"})

Sin embargo, probablemente sería mejor usar una Lista en lugar de una matriz.

Hay una discusión interesante sobre este bug/característica en el sitio del proyecto OpenJDK.

 10
Author: Jeff Olson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 16:56:59

Los genéricos de Java funcionan comprobando los tipos en tiempo de compilación e insertando los casts apropiados, pero borrando los tipos en los archivos compilados. Esto hace que las bibliotecas genéricas sean utilizables por código que no entiende los genéricos (que fue una decisión de diseño deliberada), pero lo que significa que normalmente no puede averiguar cuál es el tipo en tiempo de ejecución.

El constructor public Stack(Class<T> clazz,int capacity) requiere que pase un objeto de clase en tiempo de ejecución, lo que significa que la información de clase está disponible en tiempo de ejecución para código que lo necesita. Y la forma Class<T> significa que el compilador comprobará que el objeto de Clase que pase es precisamente el objeto de Clase para el tipo T. No es una subclase de T, no una superclase de T, sino precisamente T.

Esto significa que puede crear un objeto array del tipo apropiado en su constructor, lo que significa que el tipo de los objetos que almacena en su colección tendrá sus tipos comprobados en el momento en que se agregan a la colección.

 7
Author: Bill Michell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-11 10:07:35

Hola aunque el hilo está muerto, me gustaría llamar su atención sobre esto:

Los genéricos se utilizan para la comprobación de tipos durante el tiempo de compilación:

  • Por lo tanto, el propósito es comprobar que lo que entra es lo que necesita.
  • Lo que devuelves es lo que el consumidor necesita.
  • Comprueba esto:

introduzca la descripción de la imagen aquí

No se preocupe por encasillar las advertencias cuando esté escribiendo una clase genérica. Preocúpate cuando lo estés usando.

 6
Author: puneeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-08 10:56:23

¿Qué pasa con esta solución?

@SafeVarargs
public static <T> T[] toGenericArray(T ... elems) {
    return elems;
}

Funciona y parece demasiado simple para ser verdad. ¿Hay algún inconveniente?

 5
Author: Benjamin M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-21 01:28:56

Mira también este código:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

Convierte una lista de cualquier tipo de objeto en una matriz del mismo tipo.

 4
Author: MatheusJardimB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-08 23:32:27

He encontrado una manera rápida y fácil que funciona para mí. Tenga en cuenta que solo he utilizado esto en Java JDK 8. No se si funcionará con versiones anteriores.

Aunque no podemos instanciar una matriz genérica de un parámetro de tipo específico, podemos pasar una matriz ya creada a un constructor de clase genérica.

class GenArray <T> {
    private T theArray[]; // reference array

    // ...

    GenArray(T[] arr) {
        theArray = arr;
    }

    // Do whatever with the array...
}

Ahora en main podemos crear el array así:

class GenArrayDemo {
    public static void main(String[] args) {
        int size = 10; // array size
        // Here we can instantiate the array of the type we want, say Character (no primitive types allowed in generics)
        Character[] ar = new Character[size];

        GenArray<Character> = new Character<>(ar); // create the generic Array

        // ...

    }
}

Para mayor flexibilidad con sus arrays puede usar una lista enlazada, por ejemplo. el ArrayList y otros métodos encontrado en el Java.útil.Clase ArrayList.

 4
Author: Nik-Lz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-09 20:43:28

El ejemplo está usando Java reflection para crear un array. Hacer esto generalmente no se recomienda, ya que no es typesafe. En su lugar, lo que debe hacer es simplemente usar una Lista interna, y evitar la matriz en absoluto.

 3
Author: Ola Bini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-09 17:33:58

Hice este fragmento de código para instanciar reflexivamente una clase que se pasa por una simple utilidad de prueba automatizada.

Object attributeValue = null;
try {
    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }
    else if(!clazz.isInterface()){
        attributeValue = BeanUtils.instantiateClass(clazz);
    }
} catch (Exception e) {
    logger.debug("Cannot instanciate \"{}\"", new Object[]{clazz});
}

Tenga en cuenta este segmento:

    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }

Para iniciar el array donde Array.newInstance (clase de array, tamaño de array) . La clase puede ser primitiva (int.class) y object (Integer.clase).

BeanUtils es parte de la primavera.

 3
Author: Bobster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-31 10:39:28

No es necesario pasar el argumento de la Clase al constructor. Prueba esto.

static class GenSet<T> {
    private final T[] array;
    @SuppressWarnings("unchecked")
    public GenSet(int capacity, T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
              "Do not provide values for dummy argument.");
        Class<?> c = dummy.getClass().getComponentType();
        array = (T[])Array.newInstance(c, capacity);
    }
    @Override
    public String toString() {
        return "GenSet of " + array.getClass().getComponentType().getName()
            + "[" + array.length + "]";
    }
}

Y

GenSet<Integer> intSet = new GenSet<>(3);
System.out.println(intSet);
System.out.println(new GenSet<String>(2));

Resultado:

GenSet of java.lang.Integer[3]
GenSet of java.lang.String[2]
 3
Author: saka1029,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 05:31:38

En realidad, una forma más fácil de hacerlo, es crear una matriz de objetos y enviarla al tipo deseado como en el siguiente ejemplo:

T[] array = (T[])new Object[SIZE];

Donde SIZE es una constante y T es un identificador de tipo

 2
Author: Pedram Esmaeeli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-12 09:53:54

Pasando una lista de valores...

public <T> T[] array(T... values) {
    return values;
}
 2
Author: Rodrigo Asensio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 10:19:41

El elenco forzado sugerido por otras personas no funcionó para mí, lanzando una excepción de casting ilegal.

Sin embargo, este reparto implícito funcionó bien:

Item<K>[] array = new Item[SIZE];

Donde el elemento es una clase I definida que contiene el miembro:

private K value;

De esta manera se obtiene una matriz de tipo K (si el elemento solo tiene el valor) o cualquier tipo genérico que desee definir en el elemento de clase.

 1
Author: vnportnoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-14 21:26:33

Nadie más ha respondido a la pregunta de qué está pasando en el ejemplo que publicaste.

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;
}

Como otros han dicho, los genéricos se "borran" durante la compilación. Así que en tiempo de ejecución una instancia de un genérico no sabe cuál es su tipo de componente. La razón de esto es histórica, Sun quería agregar genéricos sin romper la interfaz existente (tanto fuente como binaria).

Los arrays por otro lado hacen conocer su tipo de componente en tiempo de ejecución.

Este ejemplo funciona alrededor del problema haciendo que el código que llama al constructor (que conoce el tipo) pase un parámetro diciéndole a la clase el tipo requerido.

Así que la aplicación construiría la clase con algo como

Stack<foo> = new Stack<foo>(foo.class,50)

Y el constructor ahora sabe (en tiempo de ejecución) cuál es el tipo de componente y puede usar esa información para construir la matriz a través de la API de reflexión.

Array.newInstance(clazz, capacity);

Finalmente tenemos un tipo cast porque el compilador no tiene forma de saber que el array devuelto por Array#newInstance() es el tipo correcto (aunque lo sepamos).

Este estilo es un poco feo, pero a veces puede ser la solución menos mala para crear tipos genéricos que necesitan conocer su tipo de componente en tiempo de ejecución por cualquier razón (creando arrays, o creando instancias de su tipo de componente, etc.).).

 1
Author: plugwash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-18 14:54:58

Encontré una especie de trabajo en torno a este problema.

La siguiente línea arroja un error de creación de matriz genérica

List<Person>[] personLists=new ArrayList<Person>()[10];

Sin embargo, si encapsulo List<Person> en una clase separada, funciona.

import java.util.ArrayList;
import java.util.List;


public class PersonList {

    List<Person> people;

    public PersonList()
    {
        people=new ArrayList<Person>();
    }
}

Puede exponer a las personas en la lista de personas de la clase a través de un getter. La siguiente línea le dará una matriz, que tiene un List<Person> en cada elemento. En otras palabras, matriz de List<Person>.

PersonList[] personLists=new PersonList[10];

Necesitaba algo como esto en algún código en el que estaba trabajando y esto es lo que hice para conseguirlo trabajo. Hasta ahora no hay problemas.

 1
Author: developer747,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-19 12:57:33

Puede crear una matriz de objetos y enviarla a E en todas partes. Sí, no es una forma muy limpia de hacerlo, pero al menos debería funcionar.

 0
Author: Esko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-09 17:46:55

Prueba esto.

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
Author: David Bernard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-13 20:37:34

Una solución fácil, aunque desordenada, para esto sería anidar una segunda clase "holder" dentro de su clase principal, y usarla para mantener sus datos.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}
 0
Author: StarMonkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-05 00:10:45

Tal vez no esté relacionado con esta pregunta, pero mientras obtenía el error" generic array creation " para usar

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

Encuentro las siguientes obras (y trabajé para mí) con @SuppressWarnings({"unchecked"}):

 Tuple<Long, String>[] tupleArray = new Tuple[10];
 0
Author: Mohsen Afshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-21 16:11:35

Me pregunto si este código crearía una matriz genérica efectiva.

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;
}

Editar: Tal vez una forma alternativa de crear un array de este tipo, si el tamaño requerido era conocido y pequeño, sería simplemente alimentar el número requerido de "null"s en el comando zeroArray?

Aunque obviamente esto no es tan versátil como usar el código createArray.

 0
Author: Cambot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-09 13:36:35

Podrías usar un molde:

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

    public GenSet(int s) {
        a = (Item[]) new Object[s];
    }
}
 0
Author: samir benzenine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-15 17:23:32

En realidad encontré una solución bastante única para evitar la incapacidad de iniciar una matriz genérica. Lo que tienes que hacer es crear una clase que tome la variable genérica T así:

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

Y luego en su clase array solo tiene que empezar así:

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

Iniciar un new Generic Invoker[] causará un problema con unchecked, pero en realidad no debería haber ningún problema.

Para obtener de la matriz debe llamar a la matriz[i].variable así:

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

El resto, tales como el cambio de tamaño de la matriz se puede hacer con matrices.copia() así:

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

Y la función add se puede agregar de la siguiente manera:

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
Author: Crab Nebula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-28 19:59:53
private E a[];
private int size;

public GenSet(int elem)
{
    size = elem;
    a = (E[]) new E[size];
}
 -1
Author: Zubair Ibrhaim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-03 06:16:21

La creación de matrices genéricas no está permitida en Java, pero puede hacerlo como

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}
 -2
Author: Irfan Ul Haq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-19 13:45:59