java8新特性之Stream中的各方法使用场景实例

首先,在Collection接口中,提供了一个默认方法stream(),用于生成Stream流

/**
  * Returns a sequential {@code Stream} with this collection as its source.
  *
  * <p>This method should be overridden when the {@link #spliterator()}
  * method cannot return a spliterator that is {@code IMMUTABLE},
  * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
  * for details.)
  *
  * @implSpec
  * The default implementation creates a sequential {@code Stream} from the
  * collection's {@code Spliterator}.
  *
  * @return a sequential {@code Stream} over the elements in this collection
  * @since 1.8
  */
 default Stream<E> stream() {
     return StreamSupport.stream(spliterator(), false);
 }

Stream类中的方法分为两大类:

  1. 返回值还是Stream/IntStream等流类型的中间操作(intermediate operation)
  2. 返回值是非流类型的终止方法(terminal operation)

中间操作:

  1. filter()方法
/**
 * Returns a stream consisting of the elements of this stream that match
 * the given predicate.
 *
 * This is an intermediate operation.
 *
 * @param predicate a predicate to apply to each element to determine if it be included
 * @return the new stream
 */
Stream<T> filter(Predicate<? super T> predicate);

这是一个中间操作,返回一个流,其中元素满足判定predicate。参数predicate为判定条件,示例:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> stream = strings.stream().filter(string -> !string.isEmpty());

以上代码,返回strings中的非空字符串组成的Stream对象。
在这里插入图片描述
2. distinct()方法

/**
 * Returns a stream consisting of the distinct elements of this stream.
 *
 * For ordered streams, the selection of distinct elements is stable
 * (for duplicated elements, the element appearing first in the encounter
 * order is preserved.)  For unordered streams, no stability guarantees
 * are made.
 *
 * This is a stateful intermediate operation

 * @return the new stream
 */
Stream<T> distinct();

distinct()方法用于去重,返回不含重复元素的流,这是一个中间方法,示例:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> stream = strings.stream().distinct();
stream.collect(Collectors.toList());

在这里插入图片描述
3. map()方法

/**
 * Returns a stream consisting of the results of applying the given
 * function to the elements of this stream.
 *
 * This is an intermediate operation.
 *
 * @param <R> The element type of the new stream
 * @param mapper a non-interfering, stateless function to apply to each element
 * @return the new stream
 */
<R> Stream<R> map(Function<? super T, ? extends R> mapper);

map方法有一个参数mapper方法,将流中元素应用给出的mapper方法后的结果集流返回,示例:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> stream = strings.stream().map(s->s+"T");
stream.collect(Collectors.toList());

以上代码效果,为流中每个元素末尾加上字母“T”
在这里插入图片描述
4. mapToInt()方法

/**
     * Returns an {@code IntStream} consisting of the results of applying the
     * given function to the elements of this stream.
     *
     * <p>This is an intermediate operation.
     *
     * @param mapper a non-interfering, stateless function to apply to each element
     * @return the new stream
     */
    IntStream mapToInt(ToIntFunction<? super T> mapper);
    LongStream mapToLong(ToLongFunction<? super T> mapper);
    DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);

mapToInt方法的参数和作用类似map方法,区别在于返回的流是IntStream类型的。类似的还有
mapToLong、mapToDouble,示例:
在这里插入图片描述
这里有一点要注意,这里的IntStream ,LongStream ,DoubleStream 对应的是基本类型int,long,double。使用List<Integer>,List<Long>,List<Double>接收结果集的时候,需要先调用boxed()方法装箱。
5.limit()方法

/**
     * Returns a stream consisting of the elements of this stream, truncated
     * to be no longer than {@code maxSize} in length.
     * This is a short-circuiting stateful intermediate operation.
     * @param maxSize the number of elements the stream should be limited to
     * @return the new stream
     * @throws IllegalArgumentException if {@code maxSize} is negative
     */
    Stream<T> limit(long maxSize);

limit是一个中间操作,参数为一个long值maxSize,表示流中元素的最大个数,返回一个截断后不大于maxSize的流。如下代码将长度为7的流截断后保留3个,示例:

List<Integer> ints = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
ints.stream().limit(3).collect(Collectors.toList());

在这里插入图片描述
6. sorted()方法

Stream<T> sorted();//按递增排序
Stream<T> sorted(Comparator<? super T> comparator);//按给定的comparator排序

sorted方法,返回排序后的stream,中间操作
7. flatMap()/flatMapToInt()/flatMapToLong()/flatMapToDouble()方法

/**
  * 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>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>
  */
  <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

区别于map()等方法,flatMap等方法是扁平化处理方法,方法注释中给出的例子:如果orders是一个订单流Stream<Order>,每个订单有一个物品集合,orders.flatMap(order -> order.getLineItems().stream()).返回所有物品组成的Stream<item>新流。
8. skip()方法

/**
* Returns a stream consisting of the remaining elements of this stream
* after discarding the first {@code n} elements of the stream.
* If this stream contains fewer than {@code n} elements then an
* empty stream will be returned.
* */
Stream<T> skip(long n);    

返回丢弃前n个元素后的流,若流中元素小于n,则返回一个空的流。

strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
strings.stream().skip(3).collect(Collectors.toList());//返回后四个元素组成的ArrayList
strings.stream().skip(8).collect(Collectors.toList());//返回空ArrayList

在这里插入图片描述
9. peek()方法

/**
     * Returns a stream consisting of the elements of this stream, additionally
     * performing the provided action on each element as elements are consumed
     * from the resulting stream.
     */
    Stream<T> peek(Consumer<? super T> action);

peek方法的存在,主要是用于支持流操作的debug,如:

strings = Arrays.asList("aaaa", "", "bbbbb", "cccc", "eeee","", "ffff");
strings.stream().filter(e -> e.length() > 3)
                 .peek(e -> System.out.println("Filtered value: " + e))
                 .map(String::toUpperCase)
                 .peek(e -> System.out.println("Mapped value: " + e))
                 .collect(Collectors.toList());

可以打印出每个节点的值,用于观察程序执行情况。
在这里插入图片描述

终止方法:

  1. count()方法
/**
 * Returns the count of elements in this stream.  This is a special case of
 * a Reduction and is equivalent to:
 *         return mapToLong(e -> 1L).sum();
 *
 * This is a terminal operation.
 *
 * @return the count of elements in this stream
 */
 long count();
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
Stream<String> stream = strings.stream().filter(string -> !string.isEmpty());

count()方法是流操作的一个终止操作,它返回流中元素的数量,等价于 mapToLong(e -> 1L).sum();,示例:
在这里插入图片描述
2. foreach方法

/**
  * Performs an action for each element of this stream.
  *
  * <p>This is a terminal operation.
  *
  * <p>The behavior of this operation is explicitly nondeterministic.
  * For parallel stream pipelines, this operation does <em>not</em>
  * guarantee to respect the encounter order of the stream, as doing so
  * would sacrifice the benefit of parallelism.  For any given element, the
  * action may be performed at whatever time and in whatever thread the
  * library chooses.  If the action accesses shared state, it is
  * responsible for providing the required synchronization.
  *
  * @param action a non-interfering action to perform on the elements
  */
 void forEach(Consumer<? super T> action);

forEach方法是一个终止方法,对流中的所有元素执行action操作。如输出流中元素加10后的值,示例:

List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
integers.forEach(x-> System.out.println(x+10));

在这里插入图片描述
3. max()/min()方法

/**
 * Returns the maximum element of this stream according to the provided
 * {@code Comparator}.  This is a special case of a
 * <a href="package-summary.html#Reduction">reduction</a>.
 *
 * <p>This is a terminal operation.
 *
 * @param comparator a non-interfering, stateless  {@code Comparator} to compare 
 * elements of this stream
 * @return an {@code Optional} describing the maximum element of this stream,
 * or an empty {@code Optional} if the stream is empty
 * @throws NullPointerException if the maximum element is null
 */
Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);

返回流中元素的最大值/最小值,示例:

List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
int max = integers.stream().max(Integer::compare).get();
int min = integers.stream().min(Integer::compare).get();

在这里插入图片描述
4. allMatch()/noneMatch()

/**
 * Returns whether all elements of this stream match the provided predicate.
 * May not evaluate the predicate on all elements if not necessary for
 * determining the result.  If the stream is empty then {@code true} is
 * returned and the predicate is not evaluated.
 */
 //short-circuiting terminal operation 有短路效果的终止操作
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);

allMatch()返回是否流中所有元素均满足给定的判定条件,若都满足,返回true;否则返回false,找到第一个不满足条件的元素,就不再判断剩下的元素是否满足条件。如果流为空,则返回true,且判定条件不生效。
noneMatch()作用于allMatch()相反,判断是否所有元素均不满足给定的条件。
5. anyMatch()


/**
  * Returns whether any elements of this stream match the provided
  * predicate.  May not evaluate the predicate on all elements if not
  * necessary for determining the result.  If the stream is empty then
  * {@code false} is returned and the predicate is not evaluated.
  */
   //short-circuiting terminal operation 有短路效果的终止操作
 boolean anyMatch(Predicate<? super T> predicate);

返回流中是否存在某个元素满足给定的判定条件,若都不满足,返回false;否则返回true,找到第一个满足条件的元素,剩余元素就不再继续作判断。如果流为空,返回false,且给定的判断不生效。
6. collect()

/**
  * @apiNote
  * The following will accumulate strings into an ArrayList:
  *     List<String> asList = stringStream.collect(Collectors.toList());
  */
  <R, A> R collect(Collector<? super T, A, R> collector);

collect()方法是一个终止操作,方法说明中给出了几种用法:

//返回一个List<T>
List<String> asList = stringStream.collect(Collectors.toList());
//将流中的person对象,按city分组,并存入map中,key为city,value为List<person>
Map<String, List<Person>> peopleByCity
              = personStream.collect(Collectors.groupingBy(Person::getCity));
//按state分组后,再按city分组
 Map<String, Map<String, List<Person>>> peopleByStateAndCity
              = personStream.collect(Collectors.groupingBy(Person::getState,
     			Collectors.groupingBy(Person::getCity)));
  1. findAny()/findFirst()
 /**
  * Returns an {@link Optional} describing some element of the stream, or an
  * empty {@code Optional} if the stream is empty.
  * @return an {@code Optional} describing some element of this stream, or an
  * empty {@code Optional} if the stream is empty
  */
 Optional<T> findAny();//返回流中的某个元素,并行处理时为了性能最大化,可能返回不同结果
 Optional<T> findFirst();//返回流中第一个元素,若流是无序的,则可能返回任一元素

如下图中,findAny() 与 findFirst()返回结果就不都是第一个元素
在这里插入图片描述
8. reduce()

/**
 * Performs a reduction on the elements of this stream, using an associative accumulation
 * function, and returns an {@code Optional} describing the reduced value, The {@code 
 * accumulator} function must be an associative function.
 */
Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);

下面三条语句的效果相同,均返回strings中字符串拼接后的结果,返回值略有差异:

strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
strings.stream().reduce(String::concat);//返回一个optional对象
strings.stream().reduce("",String::concat);//返回值类型等于第一个参数类型
strings.stream().reduce("",String::concat,String::concat);//返回值类型等于第一个参数类型

在这里插入图片描述
stream测试代码:
链接: https://pan.baidu.com/s/1ndP1lXl_E5ZOhkhtkOHLgg
提取码: vqyn

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值