2015-02-20 13 views
9

Sono relativamente nuovo a Java e ho una domanda su quale tipo di struttura dati sarebbe la migliore per il mio caso. Ho un set di dati che sono essenzialmente coppie chiave-valore, tuttavia ogni valore può corrispondere a più chiavi e ogni chiave può corrispondere a più valori. Un esempio semplificato potrebbe essere:Quale struttura dati Java è la migliore per la mappatura a più valori a due vie

  • Red-mela
  • di mela verde
  • rosso-fragola
  • Green-Uva
  • viola-uva

Considerando l'esempio di cui sopra, Devo essere in grado di restituire il colore delle mele che ho e/o quali frutti rossi ho. I dati effettivi verranno generati dinamicamente in base a un file di input in cui ogni set sarà ovunque tra 100 e 100.000 valori e ogni valore potrebbe corrispondere a centinaia di valori nell'altro set.

Quale sarebbe il modo più efficiente di archiviare e analizzare questi dati? Preferirei una soluzione come nativa di java possibile piuttosto che qualcosa come un database esterno.

This question è correlato, ma non sono sicuro di come applicare la soluzione nel mio caso dato che avrei bisogno di assegnare più valori a ciascun tasto in entrambe le direzioni.

+0

Come su una mappa? http://docs.oracle.com/javase/7/docs/api/java/util/Map.html – Koogle

+0

C'è anche questa domanda: http://stackoverflow.com/questions/2571652/java-many-to- many-association-map – Josh

+0

@Josh - Grazie, non ho trovato quella domanda nella mia ricerca. Guarderò attraverso le soluzioni per vedere se riesco a implementarle con successo per i miei dati. – user4588937

risposta

1

Suggerisco di utilizzare Guava's Table struttura. Usa il colore come chiavi della riga e frutta come chiave della colonna o viceversa. Nello specifico, HashBasedTable è adatto al tuo caso.

Come per il vostro caso d'uso, non è necessario memorizzare nulla per i valori. Tuttavia, questi Table s non consentono valori null. Si potrebbe utilizzare un manichino Boolean o qualsiasi altro valore utile statistica, ossia la data e ora di inserimento, utente, il numero di coppie di colore/frutta, ecc

Table ha i metodi necessari, come column() e row(). Tieni presente che i documenti dicono che queste strutture sono ottimizzate per l'accesso alla riga .Questo potrebbe andar bene per te se prevedi di accedere con una chiave in più rispetto all'altra.

3

Poiché non è possibile avere chiavi duplicate in uno Map, è possibile creare piuttosto un Map<Key, List<Value>> oppure, se possibile, utilizzare Guava's Multimap.

Multimap<String, String> multimap = ArrayListMultimap.create(); 
multimap.put("Red", "Apple"); 
multimap.put("Red", "Strawberry"); 

System.out.println(multimap.get("Red")); // Prints - [Apple, Strawberry] 

Ma il problema è che non puoi chiedere le chiavi di un dato oggetto, io continuo a guardare e fare e modificare se trovo qualcosa di diverso, spero che aiuta.

Tuttavia, è possibile effettuare autonomamente l'iterazione ripetendo la mappa e individuando i tasti per l'oggetto.

+1

* "Ma il problema è che non si può chiedere chiavi di un dato oggetto. "* Sembra che sarebbe stato risolto da un BiMultiMap. Non sono sicuro se questo esiste, ma è quello che si chiamerebbe. O un grafico diretto indicizzato sui nomi dei nodi. –

+0

Potrebbe non racchiudere due di questi all'interno di un oggetto personalizzato per raggiungere questo –

0

È possibile creare la propria struttura di dati personalizzata

public class MultiValueHashMap<K, V> { 
    private HashMap<K, ArrayList<V>> multivalueHashMap = new HashMap<K, ArrayList<V>>(); 

    public static void main(String[] args) { 
     MultiValueHashMap<String, String> multivaluemap = new MultiValueHashMap<String, String>(); 
     multivaluemap.put("Red", "Apple"); 
     multivaluemap.put("Green", "Apple"); 
     multivaluemap.put("Red", "Strawberry"); 
     multivaluemap.put("Green", "Grapes"); 
     multivaluemap.put("Purple", "Grapes"); 

     for(String k : multivaluemap.keySet()){ 
      System.out.println(k + " : " + multivaluemap.get(k).toString()); 
     } 
    } 

    public void put(K key, V value){ 
     if (multivalueHashMap.containsKey(key)){ 
      ArrayList<V> values = multivalueHashMap.get(key); 
      values.add(value); 
     }else{ 
      ArrayList<V> values = new ArrayList<V>(); 
      values.add(value); 
      multivalueHashMap.put(key, values); 
     } 
    } 

    public Set<K> keySet(){ 
     return multivalueHashMap.keySet(); 
    } 

    public ArrayList<V> get(K key){ 
     return multivalueHashMap.get(key); 
    } 
} 

L'uscita dovrebbe essere

Rosso: [Apple, fragola]

Viola: [Uve]

Verde: [ Apple, Uva]