Java8新特性----Stream
Stream
Stream 是用函数式编程方式在集合类上进行复杂操作的工具。
一)常用的流操作
惰性求值方法:只描述Stream,最终不产生新集合的方法(返回的还是Stream)。
及早求值方法:最终会从Stream产生值的方法。
1.创建Stream:
java.util.Collection<E>
default Stream<E> stream()
default Stream<E> paralleStream()
产生当前集合中所有元素的流,paralleStream()以并行的方式产生。
java.util.stream.Stream
static <T> Steam<T> of(T...values)
产生一个元素为给定值的流
static <T> Stream<T> empty()
产生一个不包含任何元素的流
static <T> Stream<T> generate(Supplier<T> s)
产生一个无限流,它的值是通过反复调用函数s而构建的
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
产生一个无限流,它的元素包含种子、在种子上调用f产生的值,在前一个元素上调用f产生的值
java.util.Arrays
static <T> Stream<T> stream(T[] array, int off, int len)
产生一个流,它的元素是由数组中指定范围内的元素构成。
java.util.regex.Pattern
Stream<String> splitAsStream(CharSequence input)
产生一个流,它的元素是输入中该模式界定的部分。
java.nio.file.Files
static Stream<String> lines(Path path)
static Stream<String> lines(Path path, Charset cs)
获取值产生一个流,它的元素是指定文件中的行,该文件的字符集为UTF-8,或者为指定的字符集。
java.util.function.Supplier<T> T get()
2 //该方法接受可变长度的参数
3 Stream<String> s=Stream.of("tang","jia","jiu");
7
8 Stream.generate(Supplier<T> s);
9 Stream<String> echos=Stream.generate(() -> "Echo");
Stream<Double> random = Stream.generate(Math::random);
Stream<String> pattern = Pattern.compile("\\|").splitAsStream(str);
10 //如果要创建一个行如0 1 2 3.......的无限序列可使用:
12 Stream<BigInteger> integers=Stream.iterate(BigInteger.ZERO,n -> n.add(BigInteger.ONE));
2.转换Steam
java.util.stream.Stream
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
转换一个流中的值,并产生一个新的流。
1 List<String> collected = Stream.of("a", "b", "hello")
2 .map(string -> string.toUpperCase()) //Lambda 表达式必须是 Function 接口的一实例
3 .collect(toList());
4 assertEquals(asList("A", "B", "HELLO"), collected);

Stream<T> filter(Predicate<? super T> predicate)
产生一个新的流,包含符合某种条件的所有元素。
1 List<String> beginningWithNumbers
2 = Stream.of("a", "1abc", "abc1")
3 .filter(value -> isDigit(value.charAt(0))) //必须是Predicate
4 .collect(toList());
<R> Stream<R> flatMap(Function<? super T, ? extends Steam<? extends R>> mapper)
flatMap 方法可用 Stream 替换值, 然后将多个 Stream 连接成一个 Stream
1 List<Integer> together = Stream.of(asList(1, 2), asList(3, 4))
2 .flatMap(numbers -> numbers.stream()) //必须是Function
3 .collect(toList());
4 assertEquals(asList(1, 2, 3, 4), together);
Stream<T> limit(long n)
返回一个包含前n个元素的新流。
Stream<T> skip(int n)
与之相反会丢弃掉前面的n个元素,返回新流。
static <T> Stream<T> contact(Stream<? extends T> a, Stream<? extends T> b)
拼接a和b两个流
Stream<T> distinct()
产生一个抑制了相同元素的新流。
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)
产生一个流,它的元素是当前流中所有元素按顺序排列的,第一个方法要求元素是
实现了Comparable的类的实例。
Stream<T> peek(Consumer<? super T> action)
产生一个流,它的元素与流中的元素相同,但在每次获取一个元素时,都会调用一个函数,这对调试来说非常方便。
3.得到值
java.util.stream.Stream
Optional<T> max(Comparator<? super T> compartor)
Optional<T> min(Comparator<? super T> compartor)
分别得到这个流的最大元素和最小元素
Optional<T> findFirst()
Optional<T> findAny()
分别得到这个流的第一个和任意一个元素
boolean anyMatch(Predicate<? super T> predicate)
boolean allMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)
分别在这个流中任意元素、所有元素和没有元素匹配给定断言时返回true。
这些操作都是终结操作。
4.Optional类型
Optional<T>是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象。
有效使用Optional的关键:它在值不存在的情况下会产生一个可替代物,而只有在值
存在的情况下才会使用这个值。
在没有任何匹配时,使用默认值:
String result = optionalStr.orElse("");
String result = optionalStr.orElseGet(() -> Locale.getDefault().getDisplayName());
String result = optionalStr.orElseThrow(IllegalStateException::new)
值存在是使用值:
optionalValue.ifPresent(v -> Process V);
optionalValue.ifPresent(v -> result.add(v));
//注意调用ifPresent不会返回任何值,如果想要结果可使用map
optionValue.map(results::add);
java.util.Optional
T orElse(T other)
获取Optional的值,或者在Optional为空时,产生other
T orElseGet(Supplier<? extends T> other)
获取Optional的值,或者在Optional为空时,获取调用other产生的结果
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
获取Optional的值,或者在Optional为空时,抛出异常。
void ifPresent(Consumer<? super T> consumer)
如果该Optional不为空,那么就将它的值传递给consumer
<U> Optional<U> map(Function<? super T, ? extneds U> mapper)
获取将该Optional值传递给mapper后的结果,只要这个Optional的结果不为
空且结果不为null,否则产生一个空Optional。
不适合使用Optional值的方式:
Optional<T> optionalValue = ...;
optionalValue.get().someMethod();
//并不比下面的方式安全:
T value = ...;
value.someMethod();
if (optionalValue.isPresent()) optionalValue.get().someMethod()
//并不比下面的方式简单:
if (value != null) value.someMethod();
java.util.Optional
T get()
获取Optional的值,或者在该Optional为空时,抛出NoSuchElementException。
boolean isPresent()
如果Optional不为空时,返回true。
static <T> Optional<T> of(T value)
static <T> Optional<T> ofNullable(T value)
产生一个具有给定值的Optional。如果value为null,那么第一个方法会抛出
NullPointerException对象,而第二个方法会产生一个空Optional.
static <T> Optional<T> empty()
产生一个空Optional。
<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
产生将mapper应用于当前Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional
5.收集器
java.util.stream.BaseStream
Iterator<T> iterator()
产生一个用于获取当前流中各个元素的迭代器。
java.util.stream.Stream
void forEach(Consumer<? super T> action)
在流的每个元素上调用action,这是一个终结操作,会以任意顺序遍历各个元素。
Object[] toArray()
<A> A[] toArray(IntFunction<A[]> generator)
产生一个数组对象,或者在将引用A[]::new传递给构造器时,返回一个A类型的数组。
<R, A> R collect(Collector<? super T,A,R> collector)
使用给定的收集器来收集当前流中的元素,Collectors类中有多种收集器的工厂方法。
java.util.stream.Collectors
static <T> Collector<T,?,List<T>> toList()
static <T> Collector<T,?,Set<T>> toSet()
产生一个收集器
static <T,C extends Collection<T>> Collector<T,?,C> toCollection(Supplier<C> collectionFactory)
产生一个将元素收集到任意集合中的收集器。可以传递一个诸如TreeSet::new的构造器引用。
static Collector<CharSequence,?,String> joining()
static Collector<CharSequence,?,String> joining(CharSequence delimiter)
static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
产生一个链接字符串的收集器,分隔符会置于字符串之间,而第一个字符串可之前可以有前缀,最后一个字符串之后可以有后缀。
static <T> Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFuntion<? super T> mapper)
static <T> Collector<T,?,LongSummaryStatistics> summarizingLong(ToLongFuntion<? super T> mapper)
static <T> Collector<T,?,DoubleSummaryStatistics> summarizingDouble(ToDoubleFuntion<? super T> mapper)
产生对应的SummaryStatistics收集器,通过它可以进行各自计算
IntSummaryStatistics
LongSummaryStatistics
DoubleSummaryStatistics
long getCount()
(int|long|double) getSum()
double getAverage()
(int|long|double) getMax()
(int|long|double) getMin()
收集到map中:
Map<Integer, String> idToName = users.stream().collect(Collectors.toMap
(User::getUserId, User::getName));
Map<Integer, User> userMap = users.stream().collect(Collectors
.toMap(User::getUserId, Function.identity()));
java.util.stream.Collector
static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T, ? extends K> key, Function<? super T, ? extends U> value)
key:产生Map的键 value:产生Map的值
static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T, ? extends K> key,
Function<? super T, ? extends U> value,BinaryOperator<U> mergeFunction)
如果多个元素具有相同的键就会存在冲突,收集器会抛异常。mergeFunction函数引元来覆盖这种行为,
该函数会针对给定的已有值和新值来解决冲突并确定键对应的值。这个函数该返回已有值,新值或者它们的组合。
static <T,K,U,M> Collector<T,?,M> toMap(Function<? super T, ? extends K> key,
Function<? super T, ? extends U> value,BinaryOperator<U> mergeFunction,Supplier<M> mapSupplier)
mapSupplier:例如TreeMap::new
群组和分区:
java.util.stream.Collectors
static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)
返回一个收集器,它会产生一个映射表,其键是将classifier应用于所有收集到的元素上产生的结果,
而值是由具有相同键的元素构成的一个个列表。
static <T, K> Collector<T, ?, Map<Boolean, List<T>> partitioningBy(Predicate<? super T> predicate)
产生一个收集器,它会产生一个映射表,其键是ture或者false,而值是由满足或者不满足断言的元素构成的列表。
6.下游收集器
groupingBy()方法会产生一个Map,它的每个值都是一个List。如果想要以某种方式来处理这些List,
就需要提供一个下游收集器。例如,如果想要获得Set而不是列表,那么可以使用Collector.toSet:
java.util.stream.Collectors
static <T> Collector<T,?,Long> counting()
产生一个可以对收集到的元素进行计数的收集器。
static <T> Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper)
求和
此外还有maxBy,minBy,mapping
7.聚合操作
一般来说,如果聚合方法有一个聚合操作op,那么该操作会产生v0 op v1 op v2......,其中 vi op vi+1就表示我们编写的函数调用op(vi,vi+1).
该操作应该是联合的,即与你组合元素的顺序无关。
1 Stream<Integer> values=.....;
2 Optional<Integer> sum=values.reduce((x,y) -> x+y);
通常,如果有一个标识e使得e op x=x,那么你就可以使用该元素作为计算的起点。
Optional<Integer> sum=values.reduce(0,(x,y) -> x+y);
当流为空时会返回标识值。
假设现在你有包含多个对象的流,并且希望对它的某个属性求和。
int result=words.reduce(0,
(total,word) -> total+word.length(),
(total1,total2) -> total1+total2);
Java8新特性----Stream的更多相关文章
- Java8 新特性 Stream 非短路终端操作
非短路终端操作 Java8 新特性 Stream 练习实例 非短路终端操作,就是所有的元素都遍厉完,直到最后才结束.用来收集成自己想要的数据. 方法有: 遍厉 forEach 归约 reduce 最大 ...
- Java8 新特性 Stream 短路终端操作
短路终端操作 Java8 新特性 Stream 练习实例 传入一个谓词,返回传为boolean,如果符合条件,则直接结束流. 匹配所有 allMatch 任意匹配 anymMatch 不匹配 none ...
- Java8 新特性 Stream 无状态中间操作
无状态中间操作 Java8 新特性 Stream 练习实例 中间无状态操作,可以在单个对单个的数据进行处理.比如:filter(过滤)一个元素的时候,也可以判断,比如map(映射)... 过滤 fil ...
- Java8 新特性 Stream() API
新特性里面为什么要加入流Steam() 集合是Java中使用最多的API,几乎每一个Java程序都会制造和处理集合.集合对于很多程序都是必须的,但是如果一个集合进行,分组,排序,筛选,过滤...这些操 ...
- 这可能是史上最好的 Java8 新特性 Stream 流教程
本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...
- java8新特性--Stream的基本介绍和使用
什么是Stream? Stream是一个来自数据源的元素队列并可以进行聚合操作. 数据源:流的来源. 可以是集合,数组,I/O channel, 产生器generator 等 聚合操作:类似SQL语句 ...
- Java8新特性Stream流应用示例
Java8新特性介绍 过滤集合 List<String> newList = list.stream().filter(item -> item != null).collect(C ...
- Java8 新特性 Stream 练习实例
练习实例 配合Java8 新特性 Steam() API 使用 //没有写get set 构造方法 public class Sku { private Integer skuId; private ...
- Java8 新特性Stream 的学习和使用方法
流(Stream) 流是java 8 中新引入的特性,用来处理集合中的数据,Stream 是一个来自数据源的元素队列并支持聚合操作. Java 中 Stream 不会存储元素. 数据源 流的来源. 可 ...
- java8 新特性 Stream
1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...
随机推荐
- Spring中的AOP 专题
Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...
- GoLang-Rpc编程
Rpc定义: RPC(Remote Procedure Call,远程过程调用)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络细节的应用程序通信协议. RPC协议构建于TCP或UDP, ...
- prometheus 基于文件的目标发现
prometheus 基于文件的目标发现 1.创建目录 cd /usr/local/prometheus/conf mkdir -pv targets/{nodes,docker} 2.修改prome ...
- 关于ddl(新增字段)对数据库锁表|读写操作的影响_资料
1.对一个表执行ddl(新增字段)会不会阻塞表,影响读写? 在一次项目升级之前需要执行一个新增字段的脚本(alter table...),表的数据量是260多万,执行时间是72秒,感觉略长,不知道会不 ...
- 如何解决Angular网页内嵌推特时间线无法正常显示
我最近解决了一个折磨了我好久但是解决方法却只是添加两三行代码的问题.我没有在网上找到合适的解决方案,最后是我根据官方网站和很多的帖子里的部分代码得到的启发,尝试了很久之后得到的解决方法.因为过程实在是 ...
- tex 字体斜体设置
\upshape 切换成直立的字体\itshape 切换成意大利斜体\slshape 切换成成为 slanted 的斜体\scshape 切换成小体大写 http://www.tug.dk/FontC ...
- $A,B$ 实对称 $\ra\tr((AB)^2)\leq \tr(A^2B^2)$
设 $A,B$ 是 $n$ 阶实对称矩阵. 试证: $\tr((AB)^2)\leq \tr(A^2B^2)$. 又问: 等号何时成立? 证明: 由 $$\bex \sum_i \sez{\su ...
- EffectiveC++ 第7章 模板与泛型编程
我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter 7 模版与泛型编程 Templates and Gen ...
- Java8从对象列表中取出某个属性的列表
List<属性值类型> 属性List = 对象List.stream().map(对象::get方法()).collect(Collectors.toList()); 例如: List&l ...
- 【洛谷P1303A*Bprublem】
题目描述 求两数的积. 输入输出格式 输入格式: 两行,两个数. 输出格式: 积 输入输出样例 输入样例#1: 1 2 输出样例#1: 2 说明 每个数字不超过10^2000,需用高精 这道题还是比较 ...