2011-01-24 14 views
85

Hipotéticamente, tengo 5 objetos matriz de cadena:Cómo hacer una matriz de matrices en Java

String[] array1 = new String[]; 
String[] array2 = new String[]; 
String[] array3 = new String[]; 
String[] array4 = new String[]; 
String[] array5 = new String[]; 

y yo quiero otro objeto de matriz que contiene los 5 objetos matriz de cadena. ¿Cómo lo hago? ¿Puedo ponerlo en otra matriz?

+32

preguntas Noob pueden ser graves. De hecho, con frecuencia lo son. :-) –

+2

Pregunta pertinente, y la respuesta no es obvia para quién sabe cómo se hace la alineación de la memoria. +1 – Benj

Respuesta

114

De esta manera:

String[][] arrays = { array1, array2, array3, array4, array5 }; 

o

String[][] arrays = new String[][] { array1, array2, array3, array4, array5 }; 

(Este último sintaxis puede utilizarse en tareas que no sean en el momento de la declaración de variables, mientras la sintaxis más corta solo funciona con declaraciones.)

+0

¿Podría explicar más a fondo qué hace la segunda sintaxis? No está claro para mí. –

+4

@Terence: Hace lo mismo que el primero: crea una matriz de referencias de matriz de cadenas, inicializadas en los valores array1, array2, array3, array4 y array5, cada una de las cuales es en sí misma una referencia de matriz de cadenas. –

+1

Pregunta rápida: ¿Cómo haré esto en tiempo de ejecución si no tengo idea de cuántos objetos de matriz se crearán? –

56

tratar

String[][] arrays = new String[5][]; 
+1

este es más flexible – hetaoblog

+0

¿No debería definir un tamaño fijo en su matriz? – Filip

+0

@Filip está fijado a 5. La configuración del siguiente nivel los predetermina, pero esto se puede cambiar, por lo que su configuración puede no ser útil. –

17

Si bien hay dos respuestas excelentes que le dicen cómo hacerlo, creo que falta otra respuesta: en la mayoría de los casos, no debe hacerlo en absoluto.

Las matrices son engorrosas, en la mayoría de los casos es mejor que utilices el Collection API.

Con Colecciones, puede agregar y eliminar elementos y hay Colecciones especializadas para diferentes funcionalidades (búsqueda basada en índices, clasificación, unicidad, acceso FIFO, concurrencia, etc.).

Si bien es bueno e importante saber sobre las matrices y su uso, en la mayoría de los casos el uso de Colecciones hace que las API sean mucho más manejables (por eso las nuevas bibliotecas como Google Guava apenas usan matrices).

Por lo tanto, para su escenario, preferiría una lista de listas, y me creé usando la guayaba:

List<List<String>> listOfLists = Lists.newArrayList(); 
listOfLists.add(Lists.newArrayList("abc","def","ghi")); 
listOfLists.add(Lists.newArrayList("jkl","mno","pqr")); 
+0

Un poco más complicado que String [] [], pero permite más operaciones como concatenar datos. Sin embargo, su solución no garantiza el tamaño de los datos, lo que puede ser un problema. – Benj

+0

@Benj si es necesario, siempre es posible escribir un decorador de listas que solo acepte una cierta cantidad de elementos. –

+0

Exactos, los decoradores/envoltorios son una buena forma de garantizar la coherencia. Por lo tanto, la forma en que estamos hablando es mucho más compleja que las matrices simples. Lo que he hecho es una pequeña clase de utilidad Array2D que encapsula algunos métodos básicos como exixts (...) etc. Publiqué esto a continuación. – Benj

4

no es la clase que he mencionado en el comentario que tuvimos con Sean Patrick Floyd : Lo hice con un uso peculiar que necesita WeakReference, pero puedes cambiarlo por cualquier objeto con facilidad.

Con la esperanza de que esto puede ayudar a alguien algún día :)

import java.lang.ref.WeakReference; 
import java.util.LinkedList; 
import java.util.NoSuchElementException; 
import java.util.Queue; 


/** 
* 
* @author leBenj 
*/ 
public class Array2DWeakRefsBuffered<T> 
{ 
    private final WeakReference<T>[][] _array; 
    private final Queue<T> _buffer; 

    private final int _width; 

    private final int _height; 

    private final int _bufferSize; 

    @SuppressWarnings("unchecked") 
    public Array2DWeakRefsBuffered(int w , int h , int bufferSize) 
    { 
     _width = w; 
     _height = h; 
     _bufferSize = bufferSize; 
     _array = new WeakReference[_width][_height]; 
     _buffer = new LinkedList<T>(); 
    } 

    /** 
    * Tests the existence of the encapsulated object 
    * /!\ This DOES NOT ensure that the object will be available on next call ! 
    * @param x 
    * @param y 
    * @return 
    * @throws IndexOutOfBoundsException 
    */public boolean exists(int x , int y) throws IndexOutOfBoundsException 
    { 
     if(x >= _width || x < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (get) : [ x = " + x + "]"); 
     } 
     if(y >= _height || y < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (get) : [ y = " + y + "]"); 
     } 
     if(_array[x][y] != null) 
     { 
      T elem = _array[x][y].get(); 
      if(elem != null) 
      { 
      return true; 
      } 
     } 
     return false; 
    } 

    /** 
    * Gets the encapsulated object 
    * @param x 
    * @param y 
    * @return 
    * @throws IndexOutOfBoundsException 
    * @throws NoSuchElementException 
    */ 
    public T get(int x , int y) throws IndexOutOfBoundsException , NoSuchElementException 
    { 
     T retour = null; 
     if(x >= _width || x < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (get) : [ x = " + x + "]"); 
     } 
     if(y >= _height || y < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (get) : [ y = " + y + "]"); 
     } 
     if(_array[x][y] != null) 
     { 
      retour = _array[x][y].get(); 
      if(retour == null) 
      { 
      throw new NoSuchElementException("Dereferenced WeakReference element at [ " + x + " ; " + y + "]"); 
      } 
     } 
     else 
     { 
      throw new NoSuchElementException("No WeakReference element at [ " + x + " ; " + y + "]"); 
     } 
     return retour; 
    } 

    /** 
    * Add/replace an object 
    * @param o 
    * @param x 
    * @param y 
    * @throws IndexOutOfBoundsException 
    */ 
    public void set(T o , int x , int y) throws IndexOutOfBoundsException 
    { 
     if(x >= _width || x < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (set) : [ x = " + x + "]"); 
     } 
     if(y >= _height || y < 0) 
     { 
      throw new IndexOutOfBoundsException("Index out of bounds (set) : [ y = " + y + "]"); 
     } 
     _array[x][y] = new WeakReference<T>(o); 

     // store local "visible" references : avoids deletion, works in FIFO mode 
     _buffer.add(o); 
     if(_buffer.size() > _bufferSize) 
     { 
      _buffer.poll(); 
     } 
    } 

} 

Ejemplo de cómo usarlo:

// a 5x5 array, with at most 10 elements "bufferized" -> the last 10 elements will not be taken by GC process 
Array2DWeakRefsBuffered<Image> myArray = new Array2DWeakRefsBuffered<Image>(5,5,10); 
Image img = myArray.set(anImage,0,0); 
if(myArray.exists(3,3)) 
{ 
    System.out.println("Image at 3,3 is still in memory"); 
} 
+3

+1 por su esfuerzo, pero: en lugar de inicializar sus campos int en -1 y reasignarlos en el Constructor, debe hacerlos definitivos y asignarlos * solo * en el Constructor. –

+0

@Sean: modifiqué el código (publiqué uno nuevo con "buffer sin GC", incluyendo su sabio comentario). – Benj

Cuestiones relacionadas