lukaszgo3
lukaszgo3

Reputation: 149

Java 8 Streams - Reading, logic and printing to file in a single stream

I'd like to read a file with some strings and numbers then filter numbers from strings, append all numbers in every line and print it into a new file. I know it may be a bit challenging but is it even possible to do such a thing in only one stream?

e.g input

some numbers   1   2   3
number   4   5   6
and few more number  7   8   9

e.q output

1+2+3 = 6
4+5+6 = 15
7+8+9 = 24 

My main class for testing

public class MainFiles {
    public static void main(String[] args) {

        String filePath = "src/test/recources/1000.txt";
        new FileProcesorStream().fileReader(filePath);

    }
}

and so far I did smth like this.

import java.util.stream.Stream;

public class FileProcesorStream {
    public void fileReader(String fileName) {

        try (Stream<String> streamReader = Files.lines(Paths.get(fileName));
             PrintWriter printWriter = new PrintWriter("resultStream.txt")) {

            streamReader
                    .filter(line -> line.matches("[\\d\\s]+"))
                    .forEachOrdered(printWriter::println);

        } catch (IOException e) {
            System.out.println("File not found");
            e.printStackTrace();
        }
    }
}

Is this at least a good start to solve this problem or if not with what should I start or what should I change? Of course, if it's it possible only with a single stream.

Upvotes: 2

Views: 1463

Answers (2)

Eugene
Eugene

Reputation: 120978

In java-9 if you even will upgrade, there a simpler way to get those sums (via Scanner#findAll) :

   streamReader.map(Scanner::new)
               .mapToInt(s -> s.findAll("\\d+")
                    .map(MatchResult::group)
                    .mapToInt(Integer::parseInt)
                    .sum())
               .forEachOrdered(System.out::println);

Upvotes: 0

Ousmane D.
Ousmane D.

Reputation: 56463

You can use String::replaceAll along with the regex [^\\d\\s]+ which after that specific map operation should provide us a string containing only the whitespaces and the numbers, which we then perform a String::trim operation to remove the leading and trailing whitespace.

Following that we compute the sum of the numbers for each of the lines.

streamReader
.map(line -> line.replaceAll("[^\\d\\s]+", ""))
.map(String::trim)
.mapToInt(line -> Arrays.stream(line.split(" "))
                        .map(String::trim)
                        .filter(e -> !e.isEmpty())
                        .mapToInt(Integer::parseInt)
                        .sum()
)
.forEachOrdered(printWriter::println);

Upvotes: 1

Related Questions