2015-02-20 5 views
9

Ich bin relativ neu in Java und ich habe eine Frage darüber, welche Art von Datenstruktur für meinen Fall am besten wäre. Ich habe eine Menge von Daten, die im wesentlichen Schlüssel-Wert-Paare sind, jedoch kann jeder Wert mehreren Schlüsseln entsprechen und jeder Schlüssel kann mehreren Werten entsprechen. Ein vereinfachtes Beispiel wäre:Welche Java-Datenstruktur ist am besten für Zwei-Wege-Multi-Value-Mapping

  • Red-Apple-
  • Grün-Apple-
  • Red-Erdbeere
  • Grün-Trauben
  • Purple-Trauben

das obige Beispiel betrachtet, Ich muss zurückgeben können, welche Farbe Äpfel ich habe und/oder welche roten Früchte ich habe. Die tatsächlichen Daten werden dynamisch basierend auf einer Eingabedatei erzeugt, wobei jeder Satz irgendwo zwischen 100 und 100.000 Werten liegt und jeder Wert kann hunderten von Werten in dem anderen Satz entsprechen.

Was wäre die effizienteste Methode zum Speichern und Parsen dieser Daten? Ich würde eine Java-ähnliche Lösung bevorzugen, anstatt einer externen Datenbank.

This question ist verwandt, aber ich bin mir nicht sicher, wie man die Lösung in meinem Fall anwendet, da ich jeder Taste in beiden Richtungen mehrere Werte zuweisen müsste.

+0

Wie wäre es mit einer Karte? http://docs.oracle.com/javase/7/docs/api/java/util/Map.html – Koogle

+0

Es gibt auch diese Frage: http://stackoverflow.com/questions/2571652/java-many-to- Viele-Assoziations-Karte – Josh

+0

@Josh - Danke, ich habe diese Frage bei meiner Suche nicht gefunden. Ich werde die Lösungen durchsehen, um zu sehen, ob ich sie erfolgreich für meine Daten implementieren kann. – user4588937

Antwort

1

Ich schlage vor, Sie verwenden Guava's Table Struktur. Verwenden Sie die Farbe als Zeilenschlüssel und Obst als Spaltenschlüssel oder umgekehrt. Insbesondere ist HashBasedTable für Ihren Fall gut geeignet.

Gemäß Ihrem Anwendungsfall müssten Sie nichts für die Werte speichern. Diese Table s erlauben jedoch keine null Werte. Sie könnten ein Dummy-Boolean oder anderen statistischen Nutzungswert, das heißt Datum und Zeitpunkt des Einsetzens, Benutzer, die Anzahl der Farben/Obst-Paare usw.

Table haben die Methoden verwenden, die Sie benötigen, wie column() und row(). Bedenken Sie, dass die Dokumente sagen, dass diese Strukturen für Zeilenzugriff optimiert sind.Dies könnte für Sie in Ordnung sein, wenn Sie mit einem Schlüssel mehr als mit dem anderen zugreifen möchten.

3

Da Sie in einem Map keine doppelten Schlüssel haben können, können Sie stattdessen einen Map<Key, List<Value>> erstellen, oder wenn Sie können, verwenden Sie 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] 

Aber das Problem ist, dass Sie nicht für die Schlüssel eines bestimmten Objekts fragen, werde ich halten suchen und machen und bearbeiten, wenn ich etwas anderes finden, hoffe, es hilft.

Noch können Sie das Gegenteil tun, indem Sie die Karte wiederholen und die Schlüssel für das Objekt finden. [Apfel, Erdbeere]

Lila: [Trauben]

Grün:

+1

* "Aber das Problem ist, Sie können nicht für die fragen Schlüssel eines bestimmten Objekts. "* Klingt so, als ob es von einer BiMultiMap gelöst würde. Nicht sicher, ob das existiert, aber so würde es heißen. Oder ein gerichteter Graph, der auf Knotennamen indexiert ist. –

+0

Konnten Sie nicht zwei davon in ein benutzerdefiniertes Objekt einbinden, um dies zu erreichen –

0

Sie können Ihre eigene benutzerdefinierte Datenstruktur

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

Die Ausgabe sollte

Red erstellen [ Apfel, Trauben]