Java 8新特性 Stream API 编程

2023-05-04 20:51:55 浏览数 (1)

Java8 Stream存在的必要性

为什么要使用Stream API? 解释这个问题之前,我们先看如下示例: 我们需要迭代整形list中所有大于10的元素的和。

JAVA8之前我们可能会这样编码实现:

代码语言:javascript复制
private static int sumIterator(List<Integer> list) {
    Iterator<Integer> it = list.iterator();
    int sum = 0;
    while (it.hasNext()) {
        int num = it.next();
        if (num > 10) {
            sum  = num;
        }
    }
    return sum;
}

这种方式存在3各主要的问题:

  • 我们只是想获得满足条件的sum值,但是这种做法却展示了迭代是怎样发生的,这也叫外部迭代–因为客户端程序组在处理list的迭代算法了。
  • 程序是自然连续的。但是没有使用并行处理。
  • 对于仅仅处理这样一个简单的任务而言,代码量实在太多了。

克服以上的缺陷,JAVA8 Stream API应运而生。我们可以通过stream API实现内部迭代内部迭代 有几个特性诸如 序列化地、并行地执行、根据给定的条件过滤等。

大部分的JAVA 8 Stream API 方法都是函数式接口,所以完全可以使用lambda表达式。让我们看看如何使用一行代码解决上面的问题:

代码语言:javascript复制
    /**
     * 对列表中的大于10的元素求和
     * @param list
     * @return
     */
    static int filterGreaterThan10(List<Integer> list){
        return list.stream().filter( s -> s > 10 ).mapToInt( i -> i).sum();
    }

这段代码 利用java迭代策略,filter和map会增加效率。

Collections and Java Stream

集合是持有我们待处理的值的内存数据结构,在我们处理的时候会加载到内存中去。java stream是请求数据结构。stream不会存储数据,是直接操作源数据结构(集合或数组)生成我们使用的管道数据。例如前面我们从一个list中过滤出需要的数据。

Java Stream 操作使用函数式接口,使得我们可以使用 lambda表达式编程。 Java Stream 是一次性消耗使用的,所以不能创建其引用以使将来使用。 Java Stream是支持序列化并行处理的,极大提升了大容量集合的处理速度。

所有的 Stream API 相关接口和类都在java.util.stream包下,为原始类型也指定了stream: IntStream, LongStream 和DoubleStream.

java8中的函数式接口

Java 8 Stream API中使用函数式接口的集几种方式:

Function and BiFunction

Function 表示了 使用一个参数类型作为输入,另一个参数类型作为输出。 Function<T, R > 表示:T是输入参数类型,R是返回结果类型。处理原始类型,提供了几个function: ToIntFunction, ToLongFunction, ToDoubleFunction, ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction, LongToIntFunction, LongToDoubleFunction, IntToLongFunction, IntToDoubleFunction

专门为原始类型提供的几个方法:

  • <R> Stream<R> map(Function<? super T, ? extends R> mapper)
  • IntStream mapToInt(ToIntFunction<? super T> mapper)
  • IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper)
  • <A> A[] toArray(IntFunction<A[]> generator)
  • <U> U reduce(U identity, BiFunction<U, ? super T, U>
Predicate and BiPredicate

表示了一个符合该指定条件的断言。一般用于过滤java stream中的元素。同Function一样,也为原始类型制定了方法:

  • Stream<T> filter(Predicate<? super T> predicate)
  • boolean anyMatch(Predicate<? super T> predicate)
  • boolean allMatch(Predicate<? super T> predicate)
  • boolean noneMatch(Predicate<? super T> predicate)
Consumer and BiConsumer:

动作执行,可以对java stream的元素按指定的动作依次处理。

  • Stream<T> peek(Consumer<? super T> action)
  • void forEach(Consumer<? super T> action)
  • void forEachOrdered(Consumer<? super T> action)
Supplier

在stream中我们可以通过Supplier生成新的值。

  • public static<T> Stream<T> generate(Supplier<T> s)
  • <R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)

java.util.Optional

Optional 是一个容器对象,包含还是不包含一个非null对象。 如果存在值,则 isPresent()方法返回他true,* get()*能得到值。Stream 的这些方法返回Optional:

  • Optional<T> reduce(BinaryOperator<T> accumulator)
  • Optional<T> min(Comparator<? super T> comparator)
  • Optional<T> max(Comparator<? super T> comparator)
  • Optional<T> findFirst()
  • Optional<T> findAny()

java.util.Spliterator

trySplit方法返回一个新的子集。

0 人点赞