2016-11-07 11 views
-1

Ich schreibe ein Java-Programm, das Daten aus einer CSV-Datei erhält. Für jede Datenzeile muss ich jedes Datenelement in eine Map einfügen, indem ich den entsprechenden Header als Schlüssel verwende. Zum Beispiel sollten headerRow [7] und dataElements [7] ein Schlüssel/Wert-Paar in der Map sein.Wie kann ich in Java 8 zwei Arrays gleichzeitig durchlaufen?

Unten ist der Code, wie ich es traditionell mit Hilfe von Java schreiben würde:

private Map<String, Double> readLine(String[] headerRow, String[] dataElements) { 
    Map<String, Double> headerToDataMap = new HashMap<>(); 
    for (int i=0; i < nextLine.length; i++) { 
     headerToDataMap.put(headerRow[i], Double.valueOf(dataElements[i])); 
    } 
    return headerToDataMap; 
} 

Gibt es eine Möglichkeit, dass ich diesen Code schreiben können Java 8 Streams mit - wenn man bedenkt, dass ich auf zwei Arrays bin Iterieren gleichzeitig?

+0

Leider Verfahren keine Zip gibt es – flakes

Antwort

5

Die nächste Sache, die Sie 8 würde wahrscheinlich dazu in Vanille- Java bekommen

IntStream.range(0, nextLine.length()) 
    .boxed() 
    .collect(toMap(i -> headerRow[i], i -> dataElements[i])); 
+1

gebautet Es gibt keine 'HeaderRow :: []' +1 –

+1

@PeterLawrey war denke auch, dass wäre eine nette Notation. – flakes

+0

Guava 21 wird 'Streams.zip' haben, aber ich denke, dass das später in eine' Map' verwandelt wird, ist nicht schöner. –

1

Sie sein kann etwas nur ein wenig länger mit der bifunktionellen Schnittstelle machen.

private Map<String, Double> readLine(String[] headerRow, String[] dataElements) { 
     Map<String, Double> headerToDataMap = new HashMap<>(); 
     BiFunction<String,String, KeyValue> toKeyValuePair = (s1,s2) -> new KeyValue(s1,s2); 
     IntStream.range(0, nextLine.length) 
       .mapToObj(i -> toKeyValuePair.apply(headerRow[i], dataElements[i])) 
       .collect(Collectors.toList()) 
       .stream() 
       .forEach(kv -> { 
        headerToDataMap.put(kv.getKey(), Double.valueOf(kv.getValue())); 
       }); 
     return headerToDataMap; 
    } 

Der KeyValue Typ ein einfacher Schlüssel-Wert-Instanz-Generator (Code unten)

private class KeyValue { 
     String key; 
     String value; 
     public String getKey() { 
      return key; 
     } 
     public void setKey(String key) { 
      this.key = key; 
     } 
     public String getValue() { 
      return value; 
     } 
     public void setValue(String value) { 
      this.value = value; 
     } 
     public KeyValue(String key, String value) { 
      super(); 
      this.key = key; 
      this.value = value; 
     } 
     public KeyValue() { 
      super(); 
     }  
    } 
+0

Das ist eine wirklich seltsam verdrehte Stream-Nutzung. Was ist der Sinn der intermediären '.collect (Collectors.toList()) .stream()' Schritte? Sie fügen den Operationen nichts Nützliches hinzu, nur Overhead. Sie können beide einfach entfernen. Außerdem, wenn Sie von 'collect' wissen, warum greifen Sie am Ende auf' forEach' zurück? Und warum erstellen Sie diese 'BiFunction' zuerst, nur um sie in einem anderen Lambda-Ausdruck zu verwenden, anstatt den beabsichtigten Code direkt in den Lambda-Ausdruck im 'mapToObj'-Schritt zu schreiben? – Holger

+0

@Holger danke für deine Anmerkungen. Ich werde sie so schnell wie möglich untersuchen und Feedback geben – alainlompo

Verwandte Themen