2012-03-18 23 views
6

Utilizzo delle nuove raccolte da Google Guava, http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplainedCome eseguire iterazioni su Multimap nell'ordine di inserimento?

Come si esegue il loop su una MultiMap per ciascun tasto nell'ordine di inserimento?

Per esempio

multimap = new HashMultiMap<String,String>(); 
multimap.put("1", "value1"); 
multimap.put("1", "value2"); 
multimap.put("1", "value3"); 

multimap.put("2", "value11"); 
multimap.put("2", "value22"); 
multimap.put("2", "value33"); 

multimap.put("3", "value111"); 
multimap.put("3", "value222"); 
multimap.put("3", "value333"); 

Su ogni anello ho bisogno

"value1", "value11", "value111"; 

quindi il prossimo ciclo

"value2", "value22", "value222"; 

e così via:

"value3", "value33", "value333"; 
+4

Le raccolte di hash * 'non conservano l'ordine di inserimento. – SLaks

+0

sembra che ho bisogno di usare la tabella non una MultiMap – KJW

risposta

11

Non sono sicuro che quali sono le vostre esigenze (o caso d'uso concreto), ma proverò a indovinare. Altre risposte suggeriscono l'utilizzo di Linked * Multimap o Immutable, ma per ottenere l'output desiderato (mostrato in questione) con Multimap dovrai creare una mappa di fantasia (ne parlerò più avanti) o creare per esempio tre raccolte temporanee che contengono prima, seconda e i terzi valori per ogni chiave (saranno in ordine di inserimento, se si utilizza una delle implementazioni suggerite Multimap). Preferibilmente sarebbe una delle ListMultimaps come si può iterare multimap.keySet() per ottenere liste con i valori disponibili per indice:

final ListMultimap<String,String> multimap = LinkedListMultimap.create(); 
// put values from question here 

final List<Object> firstValues = Lists.newArrayList(); 
for (final String key: multimap.keySet()) { 
    firstValues.add(multimap.get(key).get(0)); 
}  
System.out.println(firstValues); 
// prints [value1, value11, value111] 
// similar for multimap.get(key).get(1) and so on 

ma il lato negativo è che dovrete creare tre liste per voi esempio, ciò che rende questa soluzione piuttosto unflexible.Così forse sarà meglio mettere {primo, secondo, terzo} Valori raccolta alla mappa>, ciò che mi porta al punto:


Forse si dovrebbe usare Table invece?

Tabella è progettato come Una collezione che associa una coppia ordinata di chiavi, chiamato chiave riga e una colonna chiave, con un unico valore e, cosa più importante qui, ha righe e colonne viste. Userò ArrayTable qui:

final ArrayTable<String, Integer, Object> table = ArrayTable.create(
    ImmutableList.of("1", "2", "3"), ImmutableList.of(0, 1, 2)); 

table.put("1", 0, "value1"); 
table.put("1", 1, "value2"); 
table.put("1", 2, "value3"); 

table.put("2", 0, "value11"); 
table.put("2", 1, "value22"); 
table.put("2", 2, "value33"); 

table.put("3", 0, "value111"); 
table.put("3", 1, "value222"); 
table.put("3", 2, "value333"); 

for (final Integer columnKey : table.columnKeyList()) { 
    System.out.println(table.column(columnKey).values()); 
} 
// prints: 
// [value1, value11, value111] 
// [value2, value22, value222] 
// [value3, value33, value333] 

ho volutamente usato String per le chiavi di fila che sono [1, 2, 3, ...] interi infatti (come avete fatto in questione) e interi per i tasti della colonna iniziando con 0 ([0, 1, 2, ...]) per mostrare la somiglianza con l'esempio precedente usando la lista get(int) sulla raccolta di valori multimaps.

Spero che questo sarà utile, per lo più nel determinare ciò che si vuole;)

P.S. Io uso ArrayTable qui, perché ha un modo più ordinato di creare valori fissi (universo) di valori righe/chiavi di ImmutableTable, ma se la mutabilità non è richiesta, si dovrebbe usare invece con una modifica - ImmutableTable (e qualsiasi altra implementazione tabella) non 't avere il metodo columnKeyList(), ma solo columnKeySet() che fa la stessa cosa, ma è più lento per ArrayTable. E, naturalmente, è necessario utilizzare ImmutableTable.Builder o ImmutableTable.copyOf(Table).

+1

Ho finito per usare la tabella e scorrere su ogni riga, per ottenere una mappa che rappresenta l'intera riga. – KJW

2

Per il ciclo su più tasti:

for (Object key : multimap.keys()) { ... } 

È possibile anche un ciclo sulle voci:

for (Map.Entry entry : multimap.entries()) { ... } 
+0

questo è dove sono confuso, ho visto questo in una domanda precedente, ma non ero sicuro di come funziona? Restituisce tutti i valori per una chiave specifica o restituisce ogni valore associato alle chiavi? c'è un esempio di questo in azione? – KJW

4

È possibile utilizzare uno o LinkedListMultimapLinkedHashMultimap.

I due hanno un comportamento molto simile; una differenza importante è che LinkedListMultimap consente di inserire più copie della stessa coppia chiave-valore, mentre LinkedHashMultimap ne consente solo una.

Vedere Javadoc sopraindicato per ulteriori informazioni.

+0

Non sono sicuro del primo punto. Ho provato con un esempio in esecuzione e l'ordine di iterazione usando i due multimap è lo stesso usando chiavi, valori, voci e asMap. – dawww

+1

@dawww: Oops, hai ragione. Devo aver letto male la documentazione. Toglierò quel punto, grazie. :-) – ruakh

3

Io non sono del tutto chiaro quale ordine di iterazione vuoi dire, OP ...

  • Set<K> keySet() solo restituisce le chiavi.
  • Map<K, Collection<V>> asMap() restituisce le chiavi e le relative voci associate, pertanto è possibile eseguire for (Map.Entry<K, Collection<V>> entry : asMap().entrySet()) per iterare sulle chiavi e le relative raccolte associate.
  • Collection<Map.Entry<K, V>> entries() consente di scorrere le voci, ma senza necessariamente raggrupparle per chiave.

Se si desidera che le cose in ordine di inserimento, utilizzare uno dei inserimento ordinata Multimap implementazioni - LinkedHashMultimap, possibilmente LinkedListMultimap, ImmutableMultimap.

Problemi correlati