Java 8 从数组流式传输唯一字符
Java 8 Stream unique characters from array
尝试编写一个简单的程序,打印 Java8 中输入数组中的唯一单词。例如,如果输入是
String[] input = {"This", "is", "This", "not"};
程序应该输出 [T, h, i, s, n, o, t]
,元素的顺序应该遵循它们在输入中出现的相同模式。我的方法是 split
输入,然后 map
、distinct
最后 collect
到列表。但是下面的代码打印的是流列表而不是单词,我错过了什么?例如
String[] input = {"This", "is", "This", "not"};
System.out.println(Arrays.stream(input)
.map(word -> word.split(""))
.map(Arrays::stream)
.distinct()
.collect(toList()));
当前输出
[java.util.stream.ReferencePipeline$Head@548c4f57, java.util.stream.ReferencePipeline$Head@1218025c, java.util.stream.ReferencePipeline$Head@816f27d, java.util.stream.ReferencePipeline$Head@87aac27]
我很想看看 Java8 中是否有其他方法可以实现相同的目的。
您需要使用 flatMap 才能映射到流的内容。正如您注意到 Arrays::stream
生成单独的流,您想要的是将所有这些流展平为单个流,例如
System.out.println(Stream.of(input)
.map(w -> w.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList()));
输出
[T, h, i, s, n, o, t]
补充@sol4me 答案的另一个解决方案:
System.out.println(Stream.of(input).flatMapToInt(CharSequence::chars)
.distinct().mapToObj(c -> Character.valueOf((char) c))
.collect(Collectors.toList()));
可能会以更有效的方式编写。
JDK 没有定义 CharStream
,很遗憾...
Java in Action 8 : 对使用平面地图有很好的解释,我重申之前发布的解决方案并按照书中的解释进行解释。
String[] input = {"This", "is", "This", "not"};
map 函数 returns 一个流,由将给定函数应用于此流的元素的结果组成。
<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");
});
这将产生以下输出
输出:
[这,是,这,不是]
平面映射 Returns 一个流,由 " 将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。
<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);
产生输出:
[T, h, i, s, n, o, t]
[]2
尝试编写一个简单的程序,打印 Java8 中输入数组中的唯一单词。例如,如果输入是
String[] input = {"This", "is", "This", "not"};
程序应该输出 [T, h, i, s, n, o, t]
,元素的顺序应该遵循它们在输入中出现的相同模式。我的方法是 split
输入,然后 map
、distinct
最后 collect
到列表。但是下面的代码打印的是流列表而不是单词,我错过了什么?例如
String[] input = {"This", "is", "This", "not"};
System.out.println(Arrays.stream(input)
.map(word -> word.split(""))
.map(Arrays::stream)
.distinct()
.collect(toList()));
当前输出
[java.util.stream.ReferencePipeline$Head@548c4f57, java.util.stream.ReferencePipeline$Head@1218025c, java.util.stream.ReferencePipeline$Head@816f27d, java.util.stream.ReferencePipeline$Head@87aac27]
我很想看看 Java8 中是否有其他方法可以实现相同的目的。
您需要使用 flatMap 才能映射到流的内容。正如您注意到 Arrays::stream
生成单独的流,您想要的是将所有这些流展平为单个流,例如
System.out.println(Stream.of(input)
.map(w -> w.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList()));
输出
[T, h, i, s, n, o, t]
补充@sol4me 答案的另一个解决方案:
System.out.println(Stream.of(input).flatMapToInt(CharSequence::chars)
.distinct().mapToObj(c -> Character.valueOf((char) c))
.collect(Collectors.toList()));
可能会以更有效的方式编写。
JDK 没有定义 CharStream
,很遗憾...
Java in Action 8 : 对使用平面地图有很好的解释,我重申之前发布的解决方案并按照书中的解释进行解释。
String[] input = {"This", "is", "This", "not"};
map 函数 returns 一个流,由将给定函数应用于此流的元素的结果组成。
<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");
});
这将产生以下输出
输出: [这,是,这,不是]
平面映射 Returns 一个流,由 " 将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容组成的结果。
<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);
产生输出:
[T, h, i, s, n, o, t]
[