JAVA8 stream接口 中间操作和终端操作

上一篇我们介绍了stream的集中创建方式,《 java8 Stream-创建流的几种方式》,从这篇开始,我们开始介绍stream接口里的一系列方法的作用,以及使用,每个方法都会有相对应的案例的解析,让大家可以更加直观的方式,了解方法的使用,使用这些方法之前,我们先对方法的类型,进行归类,然后分类型进行讲解;下面,我们再看下接口定义

public interface Stream<T> extends BaseStream<T, Stream<T>> {

	Stream<T> filter(Predicate<? super T> predicate);

	<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);

	<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

	IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);

	LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);

	DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);

	Stream<T> distinct();

	Stream<T> sorted();

	Stream<T> sorted(Comparator<? super T> comparator);

	Stream<T> peek(Consumer<? super T> action);

	Stream<T> limit(long maxSize);

	Stream<T> skip(long n);

	void forEach(Consumer<? super T> action);

	void forEachOrdered(Consumer<? super T> action);

	Object[] toArray();

	<A> A[] toArray(IntFunction<A[]> generator);

	T reduce(T identity, BinaryOperator<T> accumulator);

	Optional<T> reduce(BinaryOperator<T> accumulator);

	<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

	<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);

	<R, A> R collect(Collector<? super T, A, R> collector);

	Optional<T> min(Comparator<? super T> comparator);

	Optional<T> max(Comparator<? super T> comparator);

	long count();

	boolean anyMatch(Predicate<? super T> predicate);

	boolean allMatch(Predicate<? super T> predicate);

	boolean noneMatch(Predicate<? super T> predicate);

	Optional<T> findFirst();

	Optional<T> findAny();

	public static <T> Builder<T> builder() {
		return new Streams.StreamBuilderImpl<>();
	}

	public static <T> Stream<T> empty() {
		return StreamSupport.stream(Spliterators.<T> emptySpliterator(), false);
	}

	public static <T> Stream<T> of(T t) {
		return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
	}

	@SafeVarargs
	@SuppressWarnings("varargs") // Creating a stream from an array is safe
	public static <T> Stream<T> of(T... values) {
		return Arrays.stream(values);
	}

	public static <T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
		Objects.requireNonNull(f);
		final Iterator<T> iterator = new Iterator<T>() {
			@SuppressWarnings("unchecked")
			T t = (T) Streams.NONE;

			@Override
			public boolean hasNext() {
				return true;
			}

			@Override
			public T next() {
				return t = (t == Streams.NONE) ? seed : f.apply(t);
			}
		};
		return StreamSupport.stream(
				Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
	}

	public static <T> Stream<T> generate(Supplier<T> s) {
		Objects.requireNonNull(s);
		return StreamSupport.stream(new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s),
				false);
	}

	public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
		Objects.requireNonNull(a);
		Objects.requireNonNull(b);

		@SuppressWarnings("unchecked")
		Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>((Spliterator<T>) a.spliterator(),
				(Spliterator<T>) b.spliterator());
		Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
		return stream.onClose(Streams.composedClose(a, b));
	}

	public interface Builder<T> extends Consumer<T> {
		@Override
		void accept(T t);

		default Builder<T> add(T t) {
			accept(t);
			return this;
		}

		Stream<T> build();

	}
}

通过抽象方法的定义,我们可以看到,这个方法,可以分成两种类型,一种返回类型为接口本身的Stream<T>,另外一种是返回其他对象类型的,返回接口类型的,我们称这些方法为中间操作,返回其他具体类型的,我们称为终端操作;

中间操作,是什么操作? 我们先看下字符串操作StringBuilder的append的方法

 @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

对,就是这样,返回对象本身;然后我们就可以像操作StringBuilder的append一样,可以连接操作;

StringBuilder sb = new StringBuilder();
		sb.append("a").append("b").append("c");

终端操作,是指返回最终的结果,例如我们常用的forEach,内部迭代;

下面附一张具体的分类的图,这个图,来自《java8实战》的第五章,我也就直接拿来使用了,不再去单独整理


先介绍到这里,我们下一篇开始,介绍流的中间操作的方法

上一篇《java8 Stream-创建流的几种方式》

猜你喜欢

转载自blog.csdn.net/qq_28410283/article/details/80634725