Java 8 Streams: reading a file with a word

I use Java 8 threads to process files, but so far always in turn.

What I want is a function that receives BufferedReader brand should read a certain number of words (divided by "\\s+") and should leave the BufferedReader in the exact position where the number of words was reached.

Now I have a version that reads the linewise file:

    final int[] wordCount = {20};
    br
          .lines()
          .map(l -> l.split("\\s+"))
          .flatMap(Arrays::stream)
          .filter(s -> {
              //Process s
              if(--wordCount[0] == 0) return true;
              return false;
          }).findFirst();

This obviously leaves the input stream at the position of the next line of the 20th word.
Is there a way to get a stream that reads less string from the input stream?


, . , , , . , .

, , Scanner Java 9 Scanner, (Scanner.tokens() Scanner.findAll()).
Streams, , , (API docs), , .

+4
1

: , :

5 a section of five words 3 three words
section 2 short section 7 this section contains a lot 
of words

:

[a, section, of, five, words]
[three, words, section]
[short, section]
[this, section, contains, a, lot, of, words]

, Stream API . . Stream API, StreamEx, headTail(), . , headTail:

/* Transform Stream of words like 2, a, b, 3, c, d, e to
   Stream of lists like [a, b], [c, d, e] */
public static StreamEx<List<String>> records(StreamEx<String> input) {
    return input.headTail((count, tail) -> 
        makeRecord(tail, Integer.parseInt(count), new ArrayList<>()));
}

private static StreamEx<List<String>> makeRecord(StreamEx<String> input, int count, 
                                                 List<String> buf) {
    return input.headTail((head, tail) -> {
        buf.add(head);
        return buf.size() == count 
                ? records(tail).prepend(buf)
                : makeRecord(tail, count, buf);
    });
}

:

String s = "5 a section of five words 3 three words\n"
        + "section 2 short section 7 this section contains a lot\n"
        + "of words";
Reader reader = new StringReader(s);
Stream<List<String>> stream = records(StreamEx.ofLines(reader)
               .flatMap(Pattern.compile("\\s+")::splitAsStream));
stream.forEach(System.out::println);

, . reader BufferedReader FileReader . : , , (, , ). , , , .


:

headTail() , , . () , (). , . records :

return input.headTail((count, tail) -> 
    makeRecord(tail, Integer.parseInt(count), new ArrayList<>()));

count: , ArrayList makeRecord . makeRecord :

return input.headTail((head, tail) -> {

head, :

    buf.add(head);

?

    return buf.size() == count 

, records tail ( , ) : .

            ? records(tail).prepend(buf)

( ).

            : makeRecord(tail, count, buf);
});
+5

Source: https://habr.com/ru/post/1627833/


All Articles