читать CSV-файл и фильтровать определенные столбцы в Lambda (Java8) - PullRequest
0 голосов
/ 11 мая 2018

Предположим, у меня есть файл с данными в формате через запятую, как показано ниже

TIMESTAMP,COUNTRYCODE,RESPONSETIME,FLAG

1544190995,US,500,Y
1723922044,GB,370,N
1711557214,US,750,Y

Мое требование: я хочу прочитать этот файл и отфильтровать данные по столбцам (TIMESTAMP и RESPONSETIME) и проверить, являются ли данные числовыми или нет.

Я пробовал, как показано ниже, но это не сработало. Может ли кто-нибудь помочь мне в этом?

BufferedReader br = new BufferedReader(new FileReader(file));

rows = br.lines().map(line -> Arrays.asList(line.split(DELIMITER))).filter(a -> a.equals("TIMESTAMP")).collect(Collectors.toList());

Ответы [ 4 ]

0 голосов
/ 12 мая 2018

Вы также можете использовать flatMap и более поздние версии для фильтрации только строки, содержащей цифры:

List<String> timeAndResponse = br.lines()
        .flatMap(s -> Arrays.stream(s.split(",")))
        .filter(s -> s.chars().allMatch(Character::isDigit))
        .collect(Collectors.toList());

В этом случае вы работаете только с потоками:

.flatMap(s -> Arrays.stream(s.split(","))) мы беремотдельную строку из файла, разделите ее на , - возьмите поток из промежуточного массива и, наконец, вызовите flatMap.Это даст нам Stream<String>, где String - это отдельная строка из исходной строки 1544190995,US,500,Y.После этого давайте оставим только числовую строку, используя фильтр.Наконец, давайте соберем все в List, который будет содержать следующие значения:

[1544190995, 500, 1723922044, 370, 1711557214, 750]

Надеюсь, это поможет.

0 голосов
/ 11 мая 2018

В настоящее время после операции map у вас есть Stream<List<String>>, и вы пытаетесь сравнить его с String, следовательно, никогда не дадите ожидаемого результата.

Теперь к решению; из того, что я могу собрать, кажется, что вы хотите сохранить всю строку, если TIMESTAMP и RESPONSETIME являются действительными целыми числами.

Один из способов сделать это:

 List<String> rows = br.lines()
            .skip(1) // skip headers
            .map(s -> new AbstractMap.SimpleEntry<>(s,s.split(DILIMETER)))
            .filter(a -> isInteger(a.getValue()[0]) && isInteger(a.getValue()[2]))
            .map(AbstractMap.SimpleEntry::getKey)
            .collect(Collectors.toList());

и функция isInteger определяется следующим образом:

public static boolean isInteger(String input)
{
      if(input == null || input.trim().isEmpty()) return false;
      for (char c : input.toCharArray())
          if (!Character.isDigit(c)) return false;
      return true;
}

Другое решение заключается в том, что если вы хотите получить List<String[]>, где каждый массив представляет отдельные данные каждой строки, то вы можете сделать:

List<String[]> rows = br.lines()
                .skip(1) // skip headers
                .map(s -> s.split(DILIMETER))
                .filter(a -> isInteger(a[0]) && isInteger(a[2]))
                .collect(Collectors.toList());

Примечание : если читаемый файл содержит только данные без заголовков, то нет необходимости выполнять операцию skip.

0 голосов
/ 11 мая 2018

проблема в том, что вы получите полный список "TIMESTAMP", который бесполезен.если формат файла всегда один и тот же, то есть порядок и количество заголовков, вы можете просто пропустить первую строку, затем прочитать каждую строку с данными и получить доступ только к столбцам с данными, которые вы хотите проверить.и может быть лучше использовать цикл for или while, чтобы можно было завершить досрочно.

boolean allNumericData = true;
do{
   String[] row = br.nextLine().split(DELIMITER)
   if(!isNumeric(row[0])||!isNumeric(row[2])){
       allNumericData = false;
   }
}while(allNumericData ||br.nextRow = null)

если заголовки могут отличаться, откройте файл и прочитайте первую строку, чтобы определить индекс данных, необходимых дляподтвердить и сделать то же, что и выше, но с найденным индексом.также это псевдокод.вам нужно будет выполнить проверку и обработку выборки и проверки на ноль в следующей строке

0 голосов
/ 11 мая 2018

В настоящее время это то, что вы делаете:

  1. читать все строки, которые дают: List<String>
  2. Вы делите это так, что вы получаете String[], и вы конвертируете его в List<String> (это правильно), но вы находитесь на карте, поэтому результат карты равен Stream<List<String>>
  3. Вы фильтруете и a является List. Вы пытаетесь сравнить List и String. Бип бип боп боп, проблема!

Как сказал @YCF_L, попробуйте без лямбды ..

...