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方法返回一个新的子集。