问题
Trying to write a simple program that will print the unique words from an input array in Java8 . For example if the input is
String[] input = {"This", "is", "This", "not"};
The program should output [T, h, i, s, n, o, t]
, the order of elements should follow the same pattern as they appear in input. My approach is to split
the input , then map
, distinct
and finally collect
it toList. But the following code is printing list of streams instead of words, what am i missing?.E.g.
String[] input = {"This", "is", "This", "not"};
System.out.println(Arrays.stream(input)
.map(word -> word.split(""))
.map(Arrays::stream)
.distinct()
.collect(toList()));
Current output
[java.util.stream.ReferencePipeline$Head@548c4f57, java.util.stream.ReferencePipeline$Head@1218025c, java.util.stream.ReferencePipeline$Head@816f27d, java.util.stream.ReferencePipeline$Head@87aac27]
I am interested to see if there are some other ways in Java8 to achieve the same.
回答1:
You need to use flatMap in order to map with the content of the stream . As you noticed that Arrays::stream
generate separate streams and what you want is to flatten all those streams into single stream E.g.
System.out.println(Stream.of(input)
.map(w -> w.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList()));
Output
[T, h, i, s, n, o, t]
回答2:
Another solution to complement @sol4me's answer:
System.out.println(Stream.of(input).flatMapToInt(CharSequence::chars)
.distinct().mapToObj(c -> Character.valueOf((char) c))
.collect(Collectors.toList()));
Could probably be written in a more efficient manner.
The JDK doesn't define CharStream
, unfortunately...
回答3:
Java in Action 8 : has nice explanation of using flat map, I am reiterate the solution which is posted earlier and giving the explanation as per the book.
String[] input = {"This", "is", "This", "not"};
map function returns a stream consisting of the results of applying the given function to the elements of this stream.
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
List<Stream<String>> steramsOfStream = Arrays.stream(input)
.map(word -> word.split(""))
.map(Arrays::stream)
.distinct().collect(Collectors.toList());
steramsOfStream.forEach(a -> {
a.forEach(System.out::print);
System.out.print("\n");
});
This will produce the following output
output : [This,is, This, not ]
flat map Returns a stream consisting of the results of " replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
List<String> listOfStringss = Arrays.stream(input)
.map(word -> word.split(""))
.flatMap(Arrays::stream)
.distinct().collect(Collectors.toList());
System.out.println(listOfStringss);
produces output : [T, h, i, s, n, o, t] [

来源:https://stackoverflow.com/questions/27881627/java-8-stream-unique-characters-from-array