Пустая карта после многократного использования Stream - PullRequest
0 голосов
/ 19 июня 2020

Я создаю две карты из разных столбцов в CSV (разделенные табуляцией)

oldVal1   newVal1   2
oldVal2   newVal1   3
oldVal3   newVal1   11
       .
       .
       .

и объединяю их вместе в конце. Позвольте мне предоставить только грязную реализацию:

public static void main(String[] args) throws FileNotFoundException {
    InputStream somefile = new FileInputStream("d:\\dummyfile.csv");

    Map<String, String> firstMap = new HashMap<>();
    Map<String, String> secondMap = new HashMap<>();

    Supplier<Stream<String>> streamSupplier = () -> new BufferedReader(new InputStreamReader(somefile, StandardCharsets.ISO_8859_1)).lines();

    firstMap = streamSupplier.get()
            .map(p -> p.split("\t"))
            .collect(
                    Collectors.groupingBy(s -> s[1],
                            Collectors.mapping(g -> g[2],
                            Collectors.joining(","))));

    secondMap = streamSupplier.get().map(p -> p.split("\t"))
            .collect(Collectors.toMap(s -> s[0],
                    s -> s[2]));

    firstMap.putAll(secondMap);
}

Проблема, с которой я столкнулся, заключается в том, что secondMap пуст.

Желаемый результат должен быть

Map<String, String>:

oldVal1 -> 2
oldVal2 -> 3
oldVal3 -> 11
newVal1 -> 2,3,11

Есть ли что-то, что мне не хватает в коде или как решить эту проблему другим способом? Спасибо за любую вашу помощь.

Ответы [ 2 ]

2 голосов
/ 19 июня 2020
Map<String, String> secondMap = streamSupplier.get().map(p -> p.split("\t"))
    .collect(Collectors.toMap(s -> s[1],
         s -> s[2]));

При выполнении вышеуказанного кода buffereReader пуст, поэтому secondMap не заполняется как исключение.

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

InputStream somefile2 = new FileInputStream("deneme.txt");
streamSupplier = () -> new BufferedReader(new InputStreamReader(somefile2, StandardCharsets.ISO_8859_1)).lines();
Map<String, String> secondMap = streamSupplier.get().map(p -> p.split("\t"))
    .collect(Collectors.toMap(s -> s[1],
         s -> s[2]));
0 голосов
/ 20 июня 2020

Вместо обработки одного и того же потока для каждого Map необходимо обрабатывать отдельные потоки, как показано ниже:

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws IOException {
        // Read all lines
        List<String> linesList = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.ISO_8859_1);

        // First map
        Map<String, String> firstMap = 
                linesList
                .stream()
                .map(p -> p.split("\t"))
                .collect(Collectors.groupingBy(s -> s[1], Collectors.mapping(g -> g[2], Collectors.joining(","))));
        System.out.println(firstMap);

        // Second map
        Map<String, String> secondMap = 
                linesList
                .stream()
                .map(p -> p.split("\t"))
                .collect(Collectors.toMap(s -> s[0], s -> s[2]));
        System.out.println(secondMap);
    }
}

Вывод:

{newVal1=2,3,11}
{oldVal2=3, oldVal3=11, oldVal1=2}
...