2010-01-12 11 views
11

Desidero utilizzare una raccolta al posto dell'array 2D in modo che non sia necessario fornire le sue dimensioni al momento della dichiarazione e posso aggiungere tutti gli elementi che desidero in modo dinamico.Quale raccolta utilizzare al posto dell'array 2D in Java?

+1

Quali modelli si intende utilizzare per accedere agli elementi dell'array? Accesso casuale, un'intera riga, un'intera colonna? –

risposta

7

Il problema con Elenco> è necessario ridimensionare ogni riga se si desidera ridimensionare la matrice.

Se si desidera utilizzare una matrice sparsa, o forse una matrice infinita si può fare qualcosa di simile:

class SparseMatrix<X> { 
    private Map<Coord, X> values = new HashMap<Coord, X>(); 

    public SparseMatrix() { 
    } 

    public X get(int x, int y) { 
    return values.put(new Coord(x,y)); // null if there's no value 
    } 

    public void set(int x, int y, X value) { // you can use null (like in a List) 
    values.set(new Coord(x,y), value); 
    } 

    private static class Coord { 
    int x; int y; 
    public Coord(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    @Override 
    public boolean equals(Object other) { 
     if (other instance of Coord) { 
      Coord o = (Coord) other; 
      return o.x == x && o.y == y; 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return o.x + o.y; // or some more clever implementation :) 
    } 

    } 
} 

Edit:Apache Commons HashCodeBuilder è un grande strumento per la generazione di hash-codici.

+1

Il tuo hashCode potrebbe traboccare - tuttavia * lo * hai commentato di conseguenza ... :) – Esko

+0

Vista nitida !!! C'è un metodo di utilità: java.util.Arrays.hashCode (int []) che crea un hashcode per un int [] ma, ovviamente, non sarebbe bello creare un array ogni volta che è necessario hashChode (o avere ha creato). Forse potremmo copiare la sua implementazione solo per due interi: (31 + o.x) * 31 + o.y. Ma sembra traboccare comunque ... (Penso che non importa, è ciclico?). – helios

+0

Ha importanza nell'hashCode() che x + y == y + x? – Adam

0

Sto utilizzando personalmente la classe Vector per questo scopo, anche se requisiti diversi possono eventualmente dettare l'uso di altre classi più specializzate.

+0

Il vettore è deprecato ed è stato sostituito da ArrayList. – Yoni

+2

@mortiz - 'java.util.Vector' dovrebbe essere generalmente evitato - la sicurezza del thread non è molto utile per la maggior parte degli scenari multi-thread e aggiunge solo un sovraccarico all'utilizzo a thread singolo. La maggior parte delle persone usa invece 'ArrayList' come tipo di' Lista' predefinito. – McDowell

+0

imparato qualcosa, grazie! – moritz

0

java.util.ArrayList è la mia scelta preferita.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html

+0

Penso che sia usato quando vogliamo avere un array 1-D dinamico –

+0

Puoi avere un ArrayList che ogni suo elemento sarebbe un altro ArrayList (come rsp e me stanno proponendo nelle nostre risposte). In questo modo, una ArrayList può essere utilizzata anche per gli array 2D. – Alex

0

Import java.util.ArrayList;

ArrayList è quello che volete, non è necessario impostare le dimensioni al momento della creazione ed è possibile aggiungere gli elementi in modo dinamico utilizzando il metodo add.

2

Il modo più semplice è quello di utilizzare le collezioni annidati ... diciamo (supponendo che i valori sono stringhe) List<List<String>> che possono poi essere utilizzate in questo modo:

List<List<String>> fakeArray = new ArrayList<List<String>>(); 

// Pretend you fill it with values between these calls 
String retrieve = fakeArray.get(0).get(0); 

Edit: Questo era in origine una Map<String,List<String>> che in realtà doesn' ha senso in questo contesto.

Tuttavia, si consiglia di vedere se Google Collections o Apache Commons Collections hanno qualcosa più specializzata che è possibile utilizzare.

0

Dipende da cosa si sta tentando di fare, ma vorrei raccomandare ArrayList. È più veloce del vettore. A meno che non ti interessi della sincronizzazione! Se lo si desidera come un elenco bidimensionale, quindi si crea un ArrayList e ogni elemento di questo elenco sarebbe un altro ArrayList.

0

È possibile eseguire una prova con un ArrayList con ArrayList s come elementi. Se ciò non fa ciò che vuoi, ti darà istantaneamente ciò di cui hai bisogno per costruirti.

2

Cosa vuoi essere in grado di fare con esso? Probabilmente userò semplicemente un Collection<Collection<Element>> (dove Collection potrebbe essere sostituito da List).

Oppure è possibile creare la propria classe con metodi per scorrere su righe o colonne o tutti gli elementi necessari.

0

Dipende dal modo in cui si desidera utilizzare la struttura dati. Le opzioni disponibili sono:

  • Due elenchi; è il tuo lavoro sincronizzare tra loro.
  • Una mappa; invece di una relazione valore-chiave, le voci della mappa saranno semplicemente tuple di oggetti.
  • Un elenco di matrici di oggetti a 2 celle; ciascun elemento della lista sarà un array oggetto di dimensioni 2.

EDIT: ho letto male completamente i questione; Pensavo si trattasse di una matrice 2D di larghezza 2.

Dopo aver letto correttamente la domanda (spero :-)), sono d'accordo con chi ha detto la lista delle liste.

Problemi correlati