别告诉我Java8都出来这么久了,你还搞不懂Stream的map和flatmap的区别?
Posted c.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了别告诉我Java8都出来这么久了,你还搞不懂Stream的map和flatmap的区别?相关的知识,希望对你有一定的参考价值。
别告诉我Java8都出来这么久了,你还搞不懂Stream的map和flatmap的区别?
Java8 map相关的方法
/**
* Returns a stream consisting of the results of applying the given
* function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
/**
* Returns an {@code IntStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">
* intermediate operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
IntStream mapToInt(ToIntFunction<? super T> mapper);
/**
* Returns a {@code LongStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
LongStream mapToLong(ToLongFunction<? super T> mapper);
/**
* Returns a {@code DoubleStream} consisting of the results of applying the
* given function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
map: 对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。这个方法有三个对于原始类型的变种方法,分别是:
mapToInt
,mapToLong
和mapToDouble
。这三个方法也比较好理解,比如mapToInt
就是把原始Stream转换成一个新的Stream,这个新生成的Stream中的元素都是int类型。之所以会有这样三个变种方法,可以免除自动装箱/拆箱的额外消耗
最通用和使用最多的就是我们的map方法了。
我们主要就是研究一下这个map方法了。
/**
* Returns a stream consisting of the results of applying the given
* function to the elements of this stream.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element
* @return the new stream
*/
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Stream 支持 map 方法,它会接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映 射成一个新的元素。
示例:
@Test
void test01(){
List<String> words = Arrays.asList("Hello", "World");
List<Integer> wordLens = words.stream()
.map(String::length) //转为字符串长度的集合
.collect(Collectors.toList());
System.out.println(wordLens);
}
运行结果:
[5, 5]
可以看到原先集合是两个元素,最后通过map之后出来的集合也是两个元素,所以他们是一个一一对应的映射关系。
Java8 flatMap相关的方法
/**
* 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. Each mapped stream is
* {@link java.util.stream.BaseStream#close() closed} after its contents
* have been placed into this stream. (If a mapped stream is {@code null}
* an empty stream is used, instead.)
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @apiNote
* The {@code flatMap()} operation has the effect of applying a one-to-many
* transformation to the elements of the stream, and then flattening the
* resulting elements into a new stream.
*
* <p><b>Examples.</b>
*
* <p>If {@code orders} is a stream of purchase orders, and each purchase
* order contains a collection of line items, then the following produces a
* stream containing all the line items in all the orders:
* <pre>{@code
* orders.flatMap(order -> order.getLineItems().stream())...
* }</pre>
*
* <p>If {@code path} is the path to a file, then the following produces a
* stream of the {@code words} contained in that file:
* <pre>{@code
* Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
* Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
* }</pre>
* The {@code mapper} function passed to {@code flatMap} splits a line,
* using a simple regular expression, into an array of words, and then
* creates a stream of words from that array.
*
* @param <R> The element type of the new stream
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element which produces a stream
* of new values
* @return the new stream
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
/**
* Returns an {@code IntStream} 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. Each mapped
* stream is {@link java.util.stream.BaseStream#close() closed} after its
* contents have been placed into this stream. (If a mapped stream is
* {@code null} an empty stream is used, instead.)
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element which produces a stream
* of new values
* @return the new stream
* @see #flatMap(Function)
*/
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
/**
* Returns an {@code LongStream} 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. Each mapped
* stream is {@link java.util.stream.BaseStream#close() closed} after its
* contents have been placed into this stream. (If a mapped stream is
* {@code null} an empty stream is used, instead.)
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element which produces a stream
* of new values
* @return the new stream
* @see #flatMap(Function)
*/
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
/**
* Returns an {@code DoubleStream} 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. Each mapped
* stream is {@link java.util.stream.BaseStream#close() closed} after its
* contents have placed been into this stream. (If a mapped stream is
* {@code null} an empty stream is used, instead.)
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function to apply to each element which produces a stream
* of new values
* @return the new stream
* @see #flatMap(Function)
*/
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
flatMap:和map类似,不同的是其每个元素转换得到的是Stream对象,会把子Stream中的元素压缩到父集合中
示例:我们需要使用flatMap找出单词列表中各不相同的字符,比如我们现在有[Hello, World]这样一个集合,然后我们要找出单词列表中各不相同的字符,最后出来的结果是[H, e, l, o, W, r, d]
@Test
void test02() {
//使用flatMap找出单词列表中各不相同的字符
List<String> words = Arrays.asList("Hello", "World");
List<String> wordMap = words.stream()
.map(word -> word.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
System.out.println(wordMap);
}
运行结果:
[H, e, l, o, W, r, d]
flatmap 方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流。
参考
【Java 8 新特性】Java 8 Stream flatMapToInt, flatMapToLong和flatMapToDouble使用示例
以上是关于别告诉我Java8都出来这么久了,你还搞不懂Stream的map和flatmap的区别?的主要内容,如果未能解决你的问题,请参考以下文章
2021年了还搞不懂Postman?快看看这阿里P8出的:如何用Postman做接口自动化测试!