JAVA8 新特性实际使用总结(一)
Optional
public final class Optional
extends Object
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
容器对象,可能包含或不包含非空值。如果存在一个值,isPresent()将返回true并 get()返回值。
Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).
还提供了依赖于包含值是否存在的其他方法,例如orElse() (如果值不存在,则返回一个默认值)以及ifPresent()(如果值存在,则 执行一个代码块)。
This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Optional may have unpredictable results and should be avoided.
这是一个基于值的类; 应该慎用相等操作(包括==,hahcode 或 synchronization) Optional可能会产生不可预知的结果,应予以避免。
个人理解
Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
常规用法
Integer a = null;
//赋值
//a=null 所以抛出 NullPointerException
Optional<Integer> optional=Optional.of(a);
// 不会抛出异常
Optional<Integer> optional = Optional.ofNullable(a);
//判空
//isNotNull=false
boolean isNotNull = optional.isPresent();
//取值
//a=null 所以抛出NoSuchElementException 否则value=a
Integer value=optional.get();
//a=null 所以value=0 否则value=a
Integer value = optional.orElse(0);
//a=null 所以不会打印 否则 打印a的值
optional.ifPresent(System.out::println);
//a=null 所以b=0 否则b=1
int b=optional.map((v)-> v++).orElse(0);
具体说明
:
of
public static <T> Optional<T> of(T value)
根据value返回一个Optional。当value为null时会报空指针异常。
参数不能为空
。
ofNullable
public static <T> Optional<T> ofNullable(T value)
根据value返回一个Optional,如果参数为null,返回一个空的Optional。
参数可以为空
。
get
public T get()
当值存在则返回值,否则(值为null)抛出NoSuchElementException异常
orElse
public T orElse(T other)
当值存在则返回值,否则(值为null)返回other的值。
orElse()方法和orElseGet()方法类似,但是orElse接受一个默认值而不是一个回调函数
isPresent
public boolean isPresent()
当值存在则返回true否则返回false,判空用
ifPresent
public void ifPresent(Consumer<? super T> consumer)
如果存在值,则使用该值调用回调函数
注意:
虽然
iPresent
函数可以当值不为空时执行回调函数,但是只能针对当前值,且无返回值。比如你想值不为null时进行加减b变量,则应该使用
map
方法进行操作。
其他实用通用的方法:
先声明一个集合后面使用:
List<String> stringCollection = new ArrayList<>();
stringCollection.add("ddd2");
stringCollection.add("aaa2");
stringCollection.add("bbb1");
stringCollection.add("aaa1");
stringCollection.add("bbb3");
stringCollection.add("ccc");
stringCollection.add("bbb2");
stringCollection.add("ddd1");
Filter 过滤
过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于中间操作,所以我们可以在过滤后的结果来应用其他Stream操作(比如forEach)。forEach需要一个函数来对过滤后的元素依次执行。forEach是一个最终操作,所以我们不能在forEach之后来执行其他Stream操作。
stringCollection
.stream()
.filter((s) -> s.startsWith("a"))
.forEach(System.out::println);
// "aaa2", "aaa1"
Sort 排序
排序是一个中间操作,返回的是排序好后的Stream。如果你不指定一个自定义的Comparator则会使用默认排序。
复制代码 代码如下:
stringCollection
.stream()
.sorted()
.filter((s) -> s.startsWith("a"))
.forEach(System.out::println);
// "aaa1", "aaa2"
需要注意的是,排序只创建了一个排列好后的Stream,而不会影响原有的数据源,排序之后原数据stringCollection是不会被修改的:
System.out.println(stringCollection);
//ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1
Map 映射
中间操作map会将元素根据指定的Function接口来依次将元素转成另外的对象,下面的示例展示了将字符串转换为大写字符串。你也可以通过map来讲对象转换成其他类型,map返回的Stream类型是根据你map传递进去的函数的返回值决定的。
stringCollection
.stream()
.map(String::toUpperCase)
.sorted((a, b) -> b.compareTo(a))
.forEach(System.out::println);
// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"
Match 匹配
Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是最终操作,并返回一个boolean类型的值。
boolean anyStartsWithA =
stringCollection
.stream()
.anyMatch((s) -> s.startsWith("a"));
System.out.println(anyStartsWithA); // true
boolean allStartsWithA =
stringCollection
.stream()
.allMatch((s) -> s.startsWith("a"));
System.out.println(allStartsWithA); // false
boolean noneStartsWithZ =
stringCollection
.stream()
.noneMatch((s) -> s.startsWith("z"));
System.out.println(noneStartsWithZ); // true
Count 计数
计数是一个最终操作,返回Stream中元素的个数,返回值类型是long。
复制代码 代码如下:
long startsWithB =
stringCollection
.stream()
.filter((s) -> s.startsWith("b"))
.count();
System.out.println(startsWithB); // 3
Reduce 规约
这是一个最终操作,允许通过指定的函数来讲stream中的多个元素规约为一个元素,规越后的结果是通过Optional接口表示的:
Optional<String> reduced =
stringCollection
.stream()
.sorted()
.reduce((s1, s2) -> s1 + "#" + s2);
reduced.ifPresent(System.out::println);
// "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"