Разделить поток

#java #collections #stream

#java #Коллекции #поток

Вопрос:

У меня есть файл. Я получаю поток, используя Files.lines. Файл большой. Мне нужно пройти через это в цикле и сформировать несколько массивов. Во время прохождения по файлу каждый сгенерированный массив должен быть передан методу, который его обработает. Я знаю, что существуют методы partitioningBy и groupingBy, но я не знаю, как применить их к моей задаче. Я пытаюсь сделать это:

 @Test
public void myTest() {
    Stream<String> lines = Stream.of(
            "some row from my file 1",
            "some row from my file 2",
            "some row from my file 3",
            "some row from my file 4",
            "some row from my file 5",
            "some row from my file n",
            "some row from my file 750000"
    );
    lines.parallel()
            .unordered()
            .collect(Collectors.partitioningBy(s -> s == 3).supplier(it -> {
                myParser(it);
            }));
}

public void myParser(List<String> myList){
    //this piece of code should give the length of the transmitted array
    System.out.println(myList.size()); 
}
  

В методе MyParser я хочу получить массивы из 3 элементов и обработать их

Комментарии:

1. В чем ваш вопрос?

2. предоставьте ожидаемый результат

3. s -> s == 3 … прочитайте, как сравнивать строки

4. @Ruslan похоже, ему не нужен вывод, он просто хочет разделить поток на фрагменты по 3 строки. Вам кажется разумным?

5. @Naman Я знаю, что есть строка, и я неправильно сравниваю ее. Могу ли я получить длину предполагаемого массива там?

Ответ №1:

Я остановлюсь подробнее на этом варианте

     ArrayList<String> list = new ArrayList<>();

    lines.forEach(it -> {
        list.add(it);
        if (list.size() > 0 amp;amp; list.size() % 3 == 0) {
            myParser(list);
            list.clear();
        }
    });
  

Ответ №2:

Вы могли бы попробовать это, чтобы разделить свой поток:

 public class T30SplitStream {

public static void main(String[] args) {
    Stream<String> lines = Stream.of("some row from my file 1", "some row from my file 2",
            "some row from my file 3", "some row from my file 4", "some row from my file 5",
            "some row from my file n", "some row from my file 750000");
    AtomicInteger i = new AtomicInteger(0);
    Map<Integer, List<String>> map = lines.parallel().unordered().map(s -> new Pair(i.incrementAndGet(), s))
            .collect(Collectors.groupingBy(p -> p.i % 3, Collectors.mapping(p -> p.s, Collectors.toList())));
    System.out.println(map);

}

public static class Pair {
    public final Integer i;
    public final String s;

    public Pair(int i, String s) {
        this.i = i;
        this.s = s;
    }
}
}
  

Ответ №3:

Решение:

 List<List<String>> partition = ListUtils.partition(lines, 3);
partition.parallelStream().forEach(this::myParser);
  

maven:

     <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.1</version>
    </dependency>