2016-11-07 3 views
-1

Я пишу программу Java, которая получает данные из файла CSV. Для каждой строки данных мне нужно поместить каждый элемент данных в карту, используя соответствующий заголовок в качестве ключа. Например, headerRow [7] и dataElements [7] должны быть пары ключ-значение на карте.В Java 8, как я могу перебирать два массива за один раз?

Ниже приведен код, как я хотел бы написать его традиционно с помощью Java:

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

Есть ли способ, что я могу написать этот код, используя Java 8 потоков - имея в виду, что я итерация на двух массивах в то же время?

+0

К сожалению, нет метода Zip встроенной – flakes

ответ

5

Ближайший вещь, которую вы можете получить это в ванильным Java 8, вероятно, будет

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

Там нет 'headerRow :: []' +1 –

+1

@PeterLawrey был также думая, что это будет аккуратная нотация. – flakes

+0

У Guava 21 будет 'Streams.zip', но я думаю, что превращение этого в« карту »впоследствии не будет приятнее этого. –

1

Вы можете сделать что-то чуть больше, используя интерфейс с BiFunction.

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

Тип KeyValue представляет собой простой генератор ключа экземпляра значение (код ниже)

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

Это действительно странно искаженное использование потока. Какова точка промежуточных шагов .collect (Collectors.toList()) .stream()? Они не добавляют ничего полезного в операции, только накладные расходы. Вы можете просто удалить оба. Кроме того, если вы знаете о 'collect', почему вы прибегаете к' forEach' в конце? И почему вы сначала создаете эту «BiFunction», просто чтобы использовать ее в другом выражении лямбда, вместо того, чтобы писать нужный код прямо в выражении лямбда на шаге «mapToObj»? – Holger

+0

@ Хольгер благодарит вас за ваши замечания. Я рассмотрю их как можно скорее и обращу – alainlompo

Смежные вопросы