Stream简介
Stream流不存储数据,它的作用是检索和逻辑处理集合数据、包括筛选、排序、统计、计数等。可以想象成是 Sql 语句。
它的源数据可以是Collection、Array等。由于它的方法参数都是函数式接口类型,所以一般和 Lambda 配合使用。
Stream流类型
1.stream 串行流
2.parallelStream 并行流,可以多线程执行,基于 ForkJoin 框架实现
常用方法
接下来我们看java.util.stream.Stream
常用方法
/**
* 返回一个串行流
*/
default Stream stream()
/**
* 返回一个并行流
*/
default Stream parallelStream()
/**
* 返回T的流
*/
public static Stream of(T t)
/**
* 返回其元素是指定值的顺序流。
*/
public static Stream of(T... values) {
return Arrays.stream(values);
}
/**
* 过滤,返回由与给定predicate匹配的该流的元素组成的流
*/
Stream filter(Predicate super T> predicate);
/**
* 此流的所有元素是否与提供的predicate匹配。
*/
boolean allMatch(Predicate super T> predicate)
/**
* 此流任意元素是否有与提供的predicate匹配。
*/
boolean anyMatch(Predicate super T> predicate);
/**
* 返回一个 Stream的构建器。
*/
public static Builder builder();
/**
* 使用 Collector对此流的元素进行归纳
*/
R collect(Collector super T, A, R> collector);
/**
* 返回此流中的元素数。
*/
long count();
/**
* 返回由该流的不同元素(根据 Object.equals(Object) )组成的流。
*/
Stream distinct();
/**
* 遍历
*/
void forEach(Consumer super T> action);
/**
* 用于获取指定数量的流,截短长度不能超过 maxSize 。
*/
Stream limit(long maxSize);
/**
* 用于映射每个元素到对应的结果
*/
Stream map(Function super T, ? extends R> mapper);
/**
* 根据提供的 Comparator进行排序。
*/
Stream sorted(Comparator super T> comparator);
/**
* 在丢弃流的第一个 n元素后,返回由该流的 n元素组成的流。
*/
Stream skip(long n);
/**
* 返回一个包含此流的元素的数组。
*/
Object[] toArray();
/**
* 使用提供的 generator函数返回一个包含此流的元素的数组,以分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。
*/
A[] toArray(IntFunction generator);
/**
* 合并流
*/
public static Stream concat(Stream extends T> a, Stream extends T> b)
具体使用示例
List strings = Arrays.asList("abc", "def", "gkh", "abc");
//返回符合条件的stream
Stream stringStream = strings.stream().filter(s -> "abc".equals(s));
//计算流符合条件的流的数量
long count = stringStream.count();
//forEach遍历->打印元素
strings.stream().forEach(System.out::println);
//limit 获取到1个元素的stream
Stream limit = strings.stream().limit(1);
//toArray 比如我们想看这个limitStream里面是什么,比如转换成String[],比如循环
String[] array = limit.toArray(String[]::new);
//map 对每个元素进行操作返回新流
Stream map = strings.stream().map(s -> s + "22");
//sorted 排序并打印
strings.stream().sorted().forEach(System.out::println);
//Collectors collect 把abc放入容器中
List collect = strings.stream().filter(string -> "abc".equals(string)).collect(Collectors.toList());
//把list转为string,各元素用,号隔开
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(","));
//对数组的统计,比如用
List number = Arrays.asList(1, 2, 5, 4);
IntSummaryStatistics statistics = number.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : "+statistics.getMax());
System.out.println("列表中最小的数 : "+statistics.getMin());
System.out.println("平均数 : "+statistics.getAverage());
System.out.println("所有数之和 : "+statistics.getSum());
//concat 合并流
List strings2 = Arrays.asList("xyz", "jqx");
Stream.concat(strings2.stream(),strings.stream()).count();
//注意 一个Stream只能操作一次,不能断开,否则会报错。
Stream stream = strings.stream();
//第一次使用
stream.limit(2);
//第二次使用
stream.forEach(System.out::println);
//报错 java.lang.IllegalStateException: stream has already been operated upon or closed
//但是可以这样, 连续使用
stream.limit(2).forEach(System.out::println);
Optional简介
Optional 是 Java8 提供的为了解决 null 安全问题的一个 API。善用 Optional 可以使我们代码中很多繁琐、丑陋的设计变得十分优雅
Stream 中的 findAny、max/min、reduce 等方法等返回 Optional 值。还有例如 IntStream.average() 返回 OptionalDouble 等等
假设有一个 Zoo 类,里面有个属性 Dog,需求要获取 Dog 的 age
class Zoo {
private Dog dog;
}
class Dog {
private int age;
}
传统解决NPE的方法
Zoo zoo = getZoo();
if(zoo != null){
Dog dog = zoo.getDog();
if(dog != null){
int age = dog.getAge();
System.out.println(age);
}
}
使用Optional后的代码
Optional.ofNullable(zoo).map(o -> o.getDog()).map(d -> d.getAge()).ifPresent(age ->
System.out.println(age)
);
Optional类中的方法
上例中Optional.ofNullable是其中一种创建 Optional 的方式。我们先看一下它的含义和其他创建 Optional 的源码方法。
创建Optional
/**
* Common instance for {@code empty()}. 全局EMPTY对象
*/
private static final Optional> EMPTY = new Optional<>();
/**
* Optional维护的值
*/
private final T value;
/**
* 如果value是null就返回EMPTY,否则就返回of(T)
*/
public static Optional ofNullable(T value) {
return value == null ? empty() : of(value);
}
/**
* 返回 EMPTY 对象
*/
public static Optional empty() {
Optional t = (Optional) EMPTY;
return t;
}
/**
* 返回Optional对象
*/
public static Optional of(T value) {
return new Optional<>(value);
}
/**
* 私有构造方法,给value赋值
*/
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
/**
* 所以如果of(T value) 的value是null,会抛出NullPointerException异常,这样貌似就没处理NPE问题
*/
public static T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
ofNullable方法和of方法唯一区别就是当 value 为 null 时,ofNullable 返回的是EMPTY,of 会抛出 NullPointerException 异常。如果需要把 NullPointerException 暴漏出来就用 of,否则就用 ofNullable。
map()相关方法
/**
* 如果value为null,返回EMPTY,否则返回Optional封装的参数值
*/
public Optional map(Function super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
/**
* 如果value为null,返回EMPTY,否则返回Optional封装的参数值,如果参数值返回null会抛 NullPointerException
*/
public Optional flatMap(Function super T, Optional> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
两个方法区别:
flatMap()参数返回值如果是 null 会抛 NullPointerException,而 map()返回EMPTY
判断 value 是否为 null
/**
* value是否为null
*/
public boolean isPresent() {
return value != null;
}
/**
* 如果value不为null执行consumer.accept
*/
public void ifPresent(Consumer super T> consumer) {
if (value != null)
consumer.accept(value);
}
获取value
/**
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
* 如果value != null 返回value,否则返回other的执行结果
*/
public T orElseGet(Supplier extends T> other) {
return value != null ? value : other.get();
}
/**
* 如果value != null 返回value,否则返回T
*/
public T orElse(T other) {
return value != null ? value : other;
}
/**
* 如果value != null 返回value,否则抛出参数返回的异常
*/
public T orElseThrow(Supplier extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
/**
* value为null抛出NoSuchElementException,不为空返回value。
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
filter()
/**
* 1. 如果是empty返回empty
* 2. predicate.test(value)==true 返回this,否则返回empty
*/
public Optional filter(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
Optional常见使用
Optional.ofNullable(zoo).map(o -> o.getDog()).map(d -> d.getAge()).filter(v->v==1).orElse(3);