Error trying to convert a List<String> to List<Integer>

I am currently trying to convert a List<String> to List<Integer> with streams and so. But I don't know what is happening; when it runs it gives me some errors that are driving me mad.

I have already tried everything I (poorly) know from Streams in Java, also tried to do without them, but the thing is that I want to make it in a functional way. I give to my method (leeFichero) a string f, which is just the path of my txt file. And all I want the method to do is return a List<Integer> with the values in it. The contents of the file is this:

-3,-2,-1,0,1,2,3
1,3,5,7,9
100
2,4,6,8,10
 public static List<Integer> leeFichero(String f) {
    List<String>lineas=null;
    try {
        BufferedReader bf = new BufferedReader(new FileReader(f));
        lineas = bf.lines().collect(Collectors.toList());
        bf.close();
    } catch (IOException e) {
        System.out.println(e.toString());
    }
    List<Integer> intList = lineas.stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());

    return intList;
} 

And when I run it, it gives me this error message:

Exception in thread "main" java.lang.NumberFormatException: For input string: "-3,-2,-1,0,1,2,3"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at ejercicios.ejercicio1.lambda$0(ejercicio1.java:108)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at ejercicios.ejercicio1.leeFichero(ejercicio1.java:108)
at ejercicios.ejercicio1.main(ejercicio1.java:48)

Upvotes: 0

Views: 745

Answers (2)

Elliott Frisch
Elliott Frisch

Reputation: 201439

First, I don't see the purpose of the many temporary variables in your method. Second, I would prefer a compiled Pattern for use in splitting the lines (here the \\s* are used to consume any whitespace that might be between digits and commas). Prefer try-with-Resources to manual resource management. Then, as already noted, use a flapMap() and then map() - but I would simply return the result(s) directly. Something like,

public static List<Integer> leeFichero(String f) {
    Pattern p = Pattern.compile("\\s*,\\s*");
    try (BufferedReader bf = new BufferedReader(new FileReader(f))) {
        return bf.lines().flatMap(s -> Arrays.stream(p.split(s)))
                .map(Integer::valueOf).collect(Collectors.toList());
    } catch (IOException e) {
        System.out.println(e.toString());
    }
    return new ArrayList<>();
}

Upvotes: 1

Naman
Naman

Reputation: 31868

You should split the lines of String using the delimeter , and flatMap them to collect as a List.

lineas = bf.lines()
        .flatMap(s -> Arrays.stream(s.split(",")))
        .collect(Collectors.toList());

then return the List<Integer> mapped as:

return lineas.stream()
        .map(Integer::parseInt)
        .collect(Collectors.toList());

Upvotes: 4

Related Questions