Issue
From given text, by using stream operations, I need to create a Map where word length is a key and List of words is a value. I need to filter out words that are no longer than 4 characters.
String text = "random.txt";
Stream<String> lines = Files.lines(Paths.get(text))
Map<Integer,List<String>> map = lines.map(line -> line.split("[\\s]+"))
.filter(word -> word.length > 4)
.collect(Collectors.groupingBy(
word -> Integer.valueOf(word[0].length()),
Collectors.mapping(word -> word[0], Collectors.toList()))
);
I must be understanding something wrong, the way I used filter is not working - throws IndexOutOfBoundsException. How should i go about excluding words that are less than 4 characters long?
I was only able to figure out how to map the first word from each line. What should I change to map every word? Thanks!
Solution
Notes after the code.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Tester {
private static Map<Integer, List<String>> byLines(String filePath) throws IOException {
Path path = Paths.get(filePath);
try (Stream<String> lines = Files.lines(path)) {
return lines.flatMap(line -> Arrays.stream(line.split("\\s+")))
.filter(word -> word.length() > 4)
.collect(Collectors.groupingBy(word -> word.length()));
}
}
public static void main(String[] args) {
try {
Map<Integer, List<String>> map = byLines("random.txt");
map.forEach((key, value) -> System.out.printf("%d: %s%n", key, value));
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
You need to call method flatMap
to create a Stream
that concatenates all the words from each line, thus converting a Stream
of lines of text to a stream of words.
Method split
(of class String
) returns an array.
Method stream
(of class Arrays
) creates a Stream
from an array.
Method flatMap
concatenates all the words from all the lines and creates a Stream
containing all the individual words in file random.txt.
Then you keep all words that contain more than 4 characters.
Then you collect the words according to your requirements, i.e. a Map
where the [map] key is the length and the [map] value is a List
containing all the words having the same length.
Answered By - Abra
Answer Checked By - Gilberto Lyons (JavaFixing Admin)