2016-07-07 21 views
0

Ich habe mit einigen Daten wie folgt zu tun, die erste Spalte ist die Handels-ID, die zweite Spalte ist die Simulations-ID (doppelt viel), die dritte Spalte ist einige dumme Datum auch ziemlich dupliziert, der vierte ist der Gegenwartswert eines Handels, meistens ist es nur 0, aber jeder andere Wert sollte ziemlich einzigartig sein.Wie konvertiert man CSV zu MultiMap in Java?

41120634|1554|20150203|-509057.56 
40998001|1554|20150203|0 
40960705|1554|20150203|0 
40998049|1554|20150203|0 
41038826|1554|20150203|0 
41081136|1554|20150203|-7198152.23 
41120653|1554|20150203|-319.436349 
41081091|1554|20150203|-4.28520907E+009 

Ich habe beschlossen, eine Datenstruktur wie folgt zu verwenden: meine csv

Map<Integer,Map<Integer,List<Map<Integer,Float>>> 

Dann wie gespeichert werden:

{20150203:{1554:[{41120634:-509057.56,41120634:0,...}]}} 

Meine Frage ist, wie man eine csv so konvertieren Datei zu meiner beabsichtigten Datenstruktur effizient?

+0

Teilen Sie, was Sie bisher versucht haben, können wir von dort aus beginnen. Es gibt keinen anderen Weg als Zeile für Zeile zu lesen, sagen wir 'List

+0

Sie haben uns nicht explizit gesagt, was die logische Hierarchie sein soll. Aus Ihrem Beispiel können wir teilweise auf "Date-> SimulationID -> ???" schließen. Wo sind 'A1: B1' usw. in Ihren Eingabedaten? Es gibt nicht genug Informationen in deiner Frage, damit jemand dir helfen kann. –

+0

Sofern Sie Ihre Daten nicht speziell wie die oben aufgelistete Struktur speichern müssen, würde ich eine Java-Klasse zum Speichern der Felder empfehlen. Dann können Sie die Zeilen einlesen und in ArrayList oder Map Steve

Antwort

3

Einfach zu implementieren wäre eine Struktur wie Map<K1, Map<K2, Map<K3, V>>>. Dieses Format heißt NestedMap, in diesem Fall NestedMap3, drei Schlüssel und ein Wert.

Es ist sehr einfach mit Vererbung zu implementieren, da ein NestedMap3 intern ein Map<K1, NestedMap2<K2, K3, V>> verwendet und die NestedMap2 verwendet ein Map<K1, Map<K2, V>>.

Weiter Sie sollten darüber nachdenken, wo ein Map und wo zu verwenden, um ein mehrere Behälter wie Pair<A, B> zu verwenden, Triple<A, B, C> usw.
Wenn Ihre Werte ändern sich häufig, einen Behälter wie Pair verwenden. Wenn Ihre Werte häufig gleich sind, verwenden Sie eine Map. Auf dieser Basis können Sie einige Werte mischen, zum Beispiel kann ein Map<K, Triple<A, B, C>> gut sein, wenn die späteren Werte häufig ändern.

In Ihrem bereitgestellten Szenario sind der zweite und dritte Wert oft identisch. Also schlage ich vor, eine NestedMap3<Integer, Integer, Integer, Float> in Ihrem Fall zu verwenden.

Zuerst wird der Code zum Einrichten der Datenstruktur, ich Ihre Eingabe übernehmen würde werden Linien als String in inputLines gespeichert gegeben:

NestedMap3<Integer, Integer, Integer, Float> map = new NestedMap3<>(); 
for (String line : inputLines) { 
    String[] values = inputLines.split("|"); 
    map.put(toInt(values[0]), toInt(values[1]), toInt(values[2]), toFloat(values[3])); 
} 

Natürlich müssen wir auch umsetzen toInt und toFloat:

public Integer toInt(final String value) { 
    return Integer.parseInt(value); 
} 

public Float toFloat(final String value) { 
    return Float.parseFloat(value); 
} 

und schließlich die Umsetzung von NestedMap3 und NestedMap2:

public class NestedMap3<K1, K2, K3, V> { 

    private final Map<K1, NestedMap2<K2, K3, V>> mK1ToK2ToK3V = 
     new HashMap<K1, NestedMap2<K2, K3, V>>(); 

    public V put(K1 key1, K2 key2, K3 key3, V value) { 
       NestedMap2<K2, K3, V> k2tok3toV = mK1ToK2ToK3V.get(key1); 
      if (k2tok3toV == null) { 
       k2tok3toV = new NestedMap2<>(); 
       mK1ToK2ToK3V.put(key1, k2tok3toV); 
      } 
     return k2tok3toV.put(key2, key3, value); 
     } 

     public V get(K1 key1, K2 key2, K3 key3) { 
       final NestedMap2<K2, K3, V> k2tok3toV = mK1ToK2ToK3V.get(key1); 
      if (k2tok3toV == null) { 
       return null; 
      } else { 
       return k2tok3toV.get(key2, key3); 
      } 
    } 

    public Map<K3, V> get(K1 key1, K2 key2) { 
     final NestedMap2<K2, K3, V> k2toV = mK1ToK2ToK3V.get(key1); 
      if (k2toV == null) { 
       return null; 
      } else { 
       return k2toV.get(key2); 
      } 
    } 

    public NestedMap2<K2, K3, V> get(K1 key1) { 
     return mK1ToK2ToK3V.get(key1); 
    } 

    public Set<K1> keySet() { 
     return mK1ToK2ToK3V.keySet(); 
    } 

    public void clear() { 
     mK1ToK2ToK3V.clear(); 
    } 
} 

public class NestedMap2<K1, K2, V> { 

    private final Map<K1, Map<K2, V>> mK1ToK2ToV = new HashMap<K1, Map<K2, V>>(); 

    public V put(K1 key1, K2 key2, V value) { 
    Map<K2, V> k2toV = mK1ToK2ToV.get(key1); 
    if (k2toV == null) { 
     k2toV = new HashMap<>(); 
     mK1ToK2ToV.put(key1, k2toV); 
    } 
    return k2toV.put(key2, value); 
    } 

    public V get(K1 key1, K2 key2) { 
    final Map<K2, V> k2toV = mK1ToK2ToV.get(key1); 
    if (k2toV == null) { 
     return null; 
    } else { 
     return k2toV.get(key2); 
    } 
    } 

    public Map<K2,V> get(K1 key1) { 
    return mK1ToK2ToV.get(key1); 
    } 

    public Set<K1> keySet() { 
    return mK1ToK2ToV.keySet(); 
    } 

    public Iterable<Pair<K1,K2>> keys2() { 
    return new Iterable<Pair<K1,K2>>() { 

     @Override 
     public Iterator<Pair<K1, K2>> iterator() { 
      return new Iterator<Pair<K1,K2>>() { 
       private Iterator<Entry<K1, Map<K2, V>>> mIterator1; 
       private Entry<K1, Map<K2, V>> mIterator1Object; 
       private Iterator<K2> mIterator2; 

       { 
        mIterator1 = mK1ToK2ToV.entrySet().iterator(); 
        if (mIterator1.hasNext()) { 
         mIterator1Object = mIterator1.next(); 
         mIterator2 = mIterator1Object.getValue().keySet().iterator(); 
        } 
       } 

       @Override 
       public boolean hasNext() { 
        if (mIterator1Object == null) { 
         return false; 
        } else { 
         return mIterator2.hasNext(); 
        } 
       } 

       @Override 
       public Pair<K1, K2> next() { 
        if (mIterator1Object == null) { 
         throw new NoSuchElementException(); 
        } else { 
         if (!mIterator2.hasNext()) { 
          if (!mIterator1.hasNext()) { 
           throw new NoSuchElementException(); 
          } else { 
           mIterator1Object = mIterator1.next(); 
           assert mIterator1Object.getValue().size() > 0 : "must contain at least one value"; 
           mIterator2 = mIterator1Object.getValue().keySet().iterator(); 
          } 
         } 
         return new Pair<K1, K2>(mIterator1Object.getKey(), mIterator2.next()); 
        } 
       } 
      }; 
     } 
    }; 

    } 

    public Iterable<Triple<K1,K2,V>> entrySet() { 
    final ArrayList<Triple<K1,K2,V>> result = new ArrayList<Triple<K1,K2,V>>(); 
    for (final Entry<K1, Map<K2, V>> entryOuter : mK1ToK2ToV.entrySet()) { 
       for (final Entry<K2, V> entryInner : entryOuter.getValue().entrySet()) { 
        result.add(new Triple<>(entryOuter.getKey(), entryInner.getKey(), entryInner.getValue())); 
       } 
    } 
    return result; 
    } 

    public void addAll(NestedMap2<K1, K2, V> nestedMap) { 
    for (final Triple<K1, K2, V> triple : nestedMap.entrySet()) { 
     this.put(triple.getFirst(), triple.getSecond(), triple.getThird()); 
    } 
    } 

    public Map<K2, V> remove(K1 k1) { 
    return mK1ToK2ToV.remove(k1); 
    } 

    public V remove(K1 k1, K2 k2) { 
     final Map<K2, V> k2ToV = mK1ToK2ToV.get(k1); 
    if (k2ToV == null) { 
       return null; 
    } else { 
       return k2ToV.remove(k2); 
    } 
    } 

    @Override 
    public String toString() { 
      return mK1ToK2ToV.toString(); 
    } 

    public void clear() { 
     mK1ToK2ToV.clear(); 
    } 
} 
+0

analysieren Teilen Sie Ihre Pair and Triple Klassenimplementierung? – Pythoner

+1

Natürlich: http://pastebin.com/kthukFdY. Triple etc. funktioniert analog. Generieren von equals & hashCode kann auch eine gute Idee sein, abhängig von der Verwendung. – Zabuza

+0

danke, ich werde meine Lösung als Referenz für andere hinzufügen. – Pythoner

1

Erstellen Sie zunächst ein Objekt, das für Ihre Daten geeignet ist, nachdem Sie CSV-Methoden von CommonApache verwendet haben. https://commons.apache.org/proper/commons-csv/

Unten habe ich einen Auszug aus einem Code gefunden, den ich gemacht habe und ich denke, dass er Ihnen nützlich sein wird.

public class csvToArray { 

    public ArrayList<data> csvTo_data() throws FileNotFoundException, IOException { 

     // Array to receive parser 
     ArrayList<data> your_data = new ArrayList<data>(); 

     // data Object to receive the CSV data 
     data yourData = new data(); 

     // call open file 
     OpenFile of = new OpenFile(); 

     // get the files in a array of files 
     File[] files = of.chosefile(); 

     // count number of files 
     int size = files.length; 

     for (int i = 0; i < size; i++) { 

      // CSV Parser can receive FileReader object, so I sent the path name 
      CSVParser parser = new CSVParser(new FileReader(files[i].getAbsolutePath()), 
        CSVFormat.DEFAULT.withSkipHeaderRecord()); 
      System.out.println("You chose to open this file:" + files[i].getName()); 

      // iterate to pass from CSV tyoe to Object data type 
      for (CSVRecord s : parser) { 

       String dataName = s.get(0); 
       String dataType = s.get(1); 
       int dataSize = Integer.parseInt(s.get(2)); 

       // get the data from file's path name 
       int date = Integer.parseInt(files[i].getName().substring(3, 7)); 

       yourData = new data(dataName , dataType , dataSize, date); 
       your_data.add(yourData); 

      } 
      parser.close(); 
     } 

     return your_data;