您的位置:首页 > 编程语言 > Java开发

Java 8新特性 Stream API 编程

2017-05-07 10:48 597 查看

Java8 Stream存在的必要性

为什么要使用Stream API? 解释这个问题之前,我们先看如下示例:

我们需要迭代整形list中所有大于10的元素的和。

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

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表达式。让我们看看如何使用一行代码解决上面的问题:

/**
* 对列表中的大于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方法返回一个新的子集。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: