2011-01-24 17 views
85

hipotetycznie, mam 5 obiektów tablicy ciągów:Jak zrobić tablicę tablic w Javie

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

i chcę inny obiekt tablica zawiera te 5 obiektów tablicy ciągów. Jak mam to zrobić? Czy mogę umieścić go w innej tablicy?

+32

Noob pytania mogą być poważne. W rzeczywistości często są. :-) –

+2

Pertinentne pytanie, a odpowiedź nie jest oczywista dla tego, kto wie, jak odbywa się wyrównanie pamięci. +1 – Benj

Odpowiedz

114

jak poniżej:

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

lub

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

(ostatnie składni mogą być stosowane w zadaniach innych niż punkt zmiennej zgłoszenia, natomiast krótsza składnia działa tylko z deklaracjami.)

+0

Czy możesz wyjaśnić, co robi druga składnia? Jest to dla mnie niejasne. –

+4

@Terence: Robi to samo, co pierwsze: Tworzy tablicę odwołań do tablicy napisów, inicjowanych do wartości tablica1, tablica2, tablica3, tablica4 i tablica5 - każda z nich jest sama w sobie odwołaniem do tablicy łańcuchów. –

+1

Szybkie pytanie: Jak to zrobić w czasie wykonywania, jeśli nie mam pojęcia, ile obiektów tablicy zostanie utworzonych? –

56

próby

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

ten jest bardziej elastyczny – hetaoblog

+0

Nie powinieneś definiować stałego rozmiaru w swojej macierzy? – Filip

+0

@Filip jest ustawiony na 5. Ustawienie następnego poziomu wstępnie je alokuje, ale można to zmienić, więc ustawienie może nie być użyteczne. –

17

Chociaż istnieją dwie doskonałe odpowiedzi, które mówią, jak to zrobić, czuję, że brakuje innej odpowiedzi: w większości przypadków nie należy tego robić w ogóle.

Tablice są uciążliwe, w większości przypadków lepiej jest korzystać z Collection API.

Za pomocą kolekcji można dodawać i usuwać elementy, a także dostępne są specjalne zbiory dla różnych funkcji (wyszukiwanie indeksowe, sortowanie, unikatowość, dostęp FIFO, współbieżność itp.).

Chociaż oczywiście dobrze jest poznać tablice i ich użycie, w większości przypadków korzystanie z kolekcji sprawia, że ​​interfejsy API są dużo łatwiejsze w zarządzaniu (dlatego nowe biblioteki, takie jak Google Guava, w ogóle nie używają tablic).

Tak, dla scenariusza, wolałbym listę list, a ja go utworzyć za pomocą Guava:

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

Nieco bardziej skomplikowany niż ciąg [] [], ale pozwala na więcej operacji, takich jak łączenie danych. Jednak twoje rozwiązanie nie zapewnia rozmiaru danych, co może stanowić problem. – Benj

+0

@Benj, jeśli to konieczne, zawsze można napisać dekorator listy, który akceptuje tylko określoną liczbę elementów. –

+0

Dokładne, dekoratory/opakowania są dobrym sposobem na zapewnienie spójności. Tak więc sposób, w jaki mówimy, jest o wiele bardziej złożony niż proste tablice. To, co zrobiłem, to mała klasa narzędziowa Array2D , która zawiera pewne podstawowe metody, takie jak exixts (...) itd. Zamieszczam to poniżej. – Benj

4

istnieje klasa I wspomniano w komentarzu mieliśmy z Sean Patrick Floyd : Zrobiłem to z osobliwym użyciem, które wymaga WeakReference, ale możesz go dowolnie zmieniać dowolnym obiektem.

Licząc to może pomóc ktoś kiedyś :)

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

} 

przykład, jak z niego korzystać:

// 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 za wysiłek, ale: zamiast inicjowania pól int do -1 i ponownego przypisania ich do Konstruktora, powinieneś zrobić je ostatecznym i przypisać je * tylko * w Konstruktorze. –

+0

@Sean: Zmodyfikowałem kod (dodałem nowy z "brakiem bufora GC", w tym twój mądry komentarz. – Benj

Powiązane problemy