首先,在Collection接口中,提供了一个默认方法stream(),用于生成Stream流:
/**
* Returns a sequential {@code Stream} with this collection as its source.
*
* This method should be overridden when the {@link #spliterator()}
* method cannot return a spliterator that is {@code IMMUTABLE},
* {@code CONCURRENT}, or late-binding. (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类中的方法分为两大类:
/**
* 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());
/**
* Returns a stream consisting of the results of applying the given
* function to the elements of this stream.
*
* This is an intermediate operation.
*
* @param 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.
*
* 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
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());
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.)
* 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:
*
{@code
* orders.flatMap(order -> order.getLineItems().stream())...
* }
*/
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
区别于map()等方法,flatMap等方法是扁平化处理方法,方法注释中给出的例子:如果orders是一个订单流Stream
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
/**
* 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());
/**
* 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.
*
* This is a terminal operation.
*
*
The behavior of this operation is explicitly nondeterministic.
* For parallel stream pipelines, this operation does not
* 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));
/**
* Returns the maximum element of this stream according to the provided
* {@code Comparator}. This is a special case of a
* reduction.
*
* 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();
/**
* 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 asList = stringStream.collect(Collectors.toList());
*/
<R, A> R collect(Collector<? super T, A, R> collector);
collect()方法是一个终止操作,方法说明中给出了几种用法:
//返回一个List
List<String> asList = stringStream.collect(Collectors.toList());
//将流中的person对象,按city分组,并存入map中,key为city,value为List
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)));
/**
* 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