Reputation: 7236
I hve this code which loops through lines of integers and enters them into a List
:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
List<List<Integer>> arr = new ArrayList<>();
IntStream.range(0, 12).forEach(i -> {
try {
arr.add(
Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList())
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
It works fine when I pass in the correct number of rows. 12 in this example. I'd like to make this dynamic so various numbers of rows could be entered. How is this done?
Upvotes: 2
Views: 136
Reputation: 29028
I'd like to make this dynamic so various numbers of rows could be entered. How is this done?
There's a couple of way to avoid hard-coding the number of lines that should be read from the console:
you can provide the expected number of lines (for instance as a method argument, or as a console input);
introduce a condition checking where a particular string (or symbol) which should signify the end of data is present in the input.
As @Slaw has mentioned in the comment, you can use BufferedReader.lines()
which generates a stream lazily populated with lines read from the BufferedReader
.
Also, note that instead of replaceAll("\\s+$", "")
which is intended to remove white trailing spaces, you can apply String.strip()
(or its predecessor trim()
).
The first option is to provide the number of rows to read explicitly and apply it via limit()
operation.
public static List<List<Integer>> readInput(int limit) {
var reader = new BufferedReader(new InputStreamReader(System.in));
return reader.lines()
.map(line -> Arrays.stream(line.strip().split(" "))
.map(Integer::parseInt)
.toList()
)
.limit(limit) // number of lines to read
.toList(); // collect(toList())
}
Another approach is to read the data until input a string representing the end of data is not encountered in the input. Since regular data in these case contains only digits and white spaces, we can make it terminating condition, i.e. read until input is valid.
public static List<List<Integer>> readInput() {
var reader = new BufferedReader(new InputStreamReader(System.in));
return reader.lines()
.takeWhile(line -> line.matches("\\d+[\\s\\d]*")) // read until there only digits in the input
.map(line -> Arrays.stream(line.strip().split(" "))
.map(Integer::parseInt)
.toList()
)
.toList(); // collect(toList())
}
Upvotes: 1