1.7. Optional类型

容器对象,可能包含或不包含非空值。如果存在一个值,isPresent()将返回true,get()将返回值。还提供了依赖于包含值是否存在的附加方法,如orElse()(如果值不存在则返回一个默认值)以及ifPresent()(如果该值存在,则执行一个代码块)。

1.7.1. 如何使用Optional值

它的值不存在的情况下会产生一个可代替物,而只有值存在的情况下才会使用这个值;

public T orElse(T other)               返回值如果存在,否则返回其他。

 public T orElse(T other) {
return value != null ? value : other;
}

public static <T> Optional<T> empty()  返回一个空的可选实例

 private static final Optional<?> EMPTY = new Optional<>();
public static<T> Optional<T> empty() {
Optional<T> t = (Optional<T>) EMPTY;
return t;
}

public T orElseGet(Supplier<? extends T> other)   如果当前值存在就返回该值,否则调用其他值并返回该调用的结果。

 public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X extends Throwable       返回包含的值(如果存在),否则抛出由供应商创建的异常。

 public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}

public <U> Optional<U> map(Function<? super T,? extends U> mapper)    如果存在值,则应用提供的映射函数,如果结果不为空,则返回一个描述结果的可选项。否则返回一个空的可选。

 public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}

public void ifPresent(Consumer<? super T> consumer)    如果存在值,则使用该值调用指定的消费者,否则不执行任何操作

 public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}

1.7.2. 实例

 public class Demo09 {

     private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt";

     public static void main(String[] args) throws Exception {

         String contens = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contens.split("\\PL+")); //获取流中的最大值,(忽略大小写)
Optional<String> maxValue = words.stream().max(String::compareToIgnoreCase);
System.out.println("maxValue:"+maxValue.orElse("")); //orElse实例
Optional<String> firstWord = words.stream()
.filter(w -> w.contains("pro"))
.findFirst();
System.out.println(firstWord.orElse("No word" + "contains pro")); //empty:返回一个空的可选实例(optionalValue == null)
Optional<String> optionalValue = firstWord.empty();
String orElseValue = optionalValue.orElse("N/A");
System.out.println("orElseValue:"+orElseValue); //orElseGet实例
String orElseGetValue = optionalValue.orElseGet(() -> Locale.getDefault().getDisplayName());
System.out.println("orElseGetValue:"+orElseGetValue); //orElseThrow实例
try {
String orElseThrowValue = optionalValue.orElseThrow(IllegalStateException::new);
System.out.println("orElseThrowValue:"+orElseThrowValue);
} catch (Throwable e) {
e.printStackTrace();
} //ifPresent实例
Optional<String> ifPresentValue = words.stream().filter(w -> w.contains("Quite")).findFirst();
ifPresentValue.ifPresent(s -> System.out.println("s:" + "contains Quite")); HashSet<String> results = new HashSet<>();
ifPresentValue.ifPresent(results :: add); //调用ifPresent时,从该函数不会返回任何值,如果想要处理函数的结果,应该使用map
Optional<Boolean> mapValue = ifPresentValue.map(results::add);
Optional<Integer> sizeValue = ifPresentValue.map(s -> results.size());
Optional<String> iteratorValue = ifPresentValue.map(s -> results.iterator().next());
System.out.println("mapValue:"+mapValue);
System.out.println("sizeValue:"+sizeValue);
System.out.println("iteratorValue:"+iteratorValue);
//mapValue具有三种值:在ifPresentValue存在的情况下包装在Optional中的true或false,
//以及ifPresentValue不存在的情况下的空Optional
}
}

1.7.3. 不适合使用Optional值的方式

public T get()         如果此可选中存在值,则返回该值,否则引发NoSuchElementException;

Get方法会在Optional值存在的情况下获得其中包装元素,或者在不存在的情况下抛出一个NoSuchElementException对象;

public boolean isPresent()  如果该Optional不为空,则返回true;

 public class Demo10 {

     private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt";

     public static void main(String[] args) throws Exception {

         String contens = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contens.split("\\PL+"));
Optional<String> word = words.stream().filter(w -> w.contains("Quite")).findFirst();
if(word.isPresent()){
String w = word.get().toUpperCase();
System.out.println(w);
}else{
String orElseValue = word.orElse("not contains Quite");
System.out.println("orElseValue:"+orElseValue);
}
}
}

1.7.4. 创建Optional值

public static <T> Optional<T> ofNullable(T value)    该方法被用来作为可能出现的null值和可选值之间的桥梁,Optional. ofNullable(obj)会在obj不为null的情况下返回Optional.of(obj),否则会返回Optional.empty();

public static <T> Optional<T> of(T value)                返回指定的当前非空值的Optional。

public static <T> Optional<T> empty()                      返回一个空的可选实例。 没有值是这个可选的。

 public class Demo11 {

 public static void main(String[] args) {

         //Optional.ofNullable(obj):obj不为空,返回一个Optional.of(obj)
String s = "123";
Optional<String> s1 = Optional.ofNullable(s);
System.out.println(s1); //输出:Optional[123]
//Optional.ofNullable(obj):obj为空,返回一个Optional.empty();
String ss1 = "";
Optional<String> ss = Optional.ofNullable(ss1);
System.out.println(ss); //输出:Optional[]
}
}

1.7.5. 用faltMAP来构建Optional值的函数

假设你有一个可以产生Optional<T>对象的方法F,并且目标类型T具有一个可以产生Optional<U>对象的方法G;如果都是普通的方法,那么可以通过调用s.f().g()来将他们组合起来,但是这种组合没法工作;

需要这样调用:

Optional<U> result = s.f().flatmap(T :: G);

 public class Demo12 {

     public static void main(String[] args) {

         //Demo12 :: squareRoot,这种格式表示:Demo12类中名为squareRoot的方法
Optional<Double> result = inverse(2.0).flatMap(Demo12 :: squareRoot);
if(result.isPresent()){
Double orElseValue = result.orElse(0.0);
System.out.println("orElseValue:"+orElseValue);
} //实例2
System.out.println("实例1:"+inverse(4.0).flatMap(Demo12 :: squareRoot));
System.out.println("实例2:"+inverse(-1.0).flatMap(Demo12 :: squareRoot));
System.out.println("实例3:"+inverse(0.0).flatMap(Demo12 :: squareRoot)); System.out.println("实例4:"+Optional.of(-0.4).flatMap(Demo12 :: inverse).flatMap(Demo12 :: squareRoot));
} public static Optional<Double> inverse(Double x){ return x == 0 ? Optional.empty() : Optional.of(1/x);
}
//平方根计算
public static Optional<Double> squareRoot(Double x){ return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
}
}

Java SE 8 流库(三)的更多相关文章

  1. Java SE 8 流库

    1. 流的作用 通过使用流,说明想要完成什么任务,而不是说明如何去实现它,将操作的调度留给具体实现去解决: 实例:假如我们想要计算某个属性的平均值,那么我们就可以指定数据源和属性,然后,流库就可以对计 ...

  2. Java SE 8 流库(一)

    1. 流的作用 通过使用流,说明想要完成什么任务,而不是说明如何去实现它,将操作的调度留给具体实现去解决: 实例:假如我们想要计算某个属性的平均值,那么我们就可以指定数据源和属性,然后,流库就可以对计 ...

  3. Java SE 8 流库(二)

    1.3. filter,map,flatMAP方法 流的转换会产生一个新流,它的元素派生出自另一个流中的元素: Stream<T> filter(Predicate<? super ...

  4. Java SE 8 流库(四)

    1.8. 收集数据 <R,A> R collect(Collector<? super T,A,R> collector)   使用给定的收集器来收集当前流中的元素 void ...

  5. Java基础IO流(三)字符流

    字符流: 文本和文本文件: java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)文件是byte byte byte....的数据序列,而文本文件是文本(char)序列 ...

  6. 第01章-Java SE8的流库

    从迭代到流的操作 流表面上看起来和集合很类似,都可以让我们转换和获取数据,但是它们之间存在着显著的差异 流并不存储其元素,这些元素可能存储在底层的集合中,或者是按需生成的 流的操作不会修改其数据源 流 ...

  7. Java高级特性1_流库_初体验

    Java高级特性流库_初体验 面对结果编程 在编程里, 有两种编程方式, 一种是面对过程编程, 一种是面对结果编程. 两者区别如下 面向过程编程 面向过程编程需要编程程序让程序依次执行得到自己想要的结 ...

  8. 在 Java SE 6 中监视和诊断性能问题

    Java™ Platform, Standard Edition 6 (Java SE) 专注于提升性能,提供的增强工具可以管理和监视应用程序以及诊断常见的问题.本文将介绍 Java SE 平台中监视 ...

  9. Java SE 8 的流库学习笔记

    前言:流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图.如: //使用foreach迭代 long count = 0; for (String w : words) { if (w. ...

随机推荐

  1. Servlet之过滤器(Filter)和监听器(Listener)

    过滤器 过滤器是一个java组件,可以拦截发送至某个servelet,jsp页面或静态页面的请求,可以在响应发送到客户之前进行拦截 工作原理: 过滤器类必须实现 Filter 接口,包含的方法如下: ...

  2. Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

    目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...

  3. OpenCASCADE 参数曲线曲面面积

    OpenCASCADE 参数曲线曲面面积 eryar@163.com Abstract. 本文介绍了参数曲面的第一基本公式,并应用曲面的第一基本公式,结合OpenCASCADE中计算多重积分的类,对任 ...

  4. Dubbo源码学习--服务发布(ProxyFactory、Invoker)

    上文分析了Dubbo服务发布的整体流程,但服务代理生成的具体细节介绍得还不是很详细.下面将会接着上文继续分析.上文介绍了服务代理生成的切入点,如下: Invoker<?> invoker ...

  5. hdu 1150 Machine Schedule 最小覆盖点集

    题意:x,y两台机器各在一边,分别有模式x0 x1 x2 ... xn, y0 y1 y2 ... ym, 现在对给定K个任务,每个任务可以用xi模式或者yj模式完成,同时变换一次模式需要重新启动一次 ...

  6. CCF-201512-1-数位之和

    问题描述 试题编号: 201512-1 试题名称: 数位之和 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个十进制整数n,输出n的各位数字之和. 输入格式 输入一个整 ...

  7. Servlet实践--留言板-v1

    功能介绍: 由三个jsp页面组成,在doGet中根据请求URL中的请求参数不同,跳转到不同的页面: 页面1:显示整个留言板列表 页面2:创建留言页面(包括用户.主题.内容和上传文件) 页面3:在查看单 ...

  8. python面向对象其他相关-异常处理-反射

    1.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象   2.issubclass(sub, super) 检查sub类是否是 super 类的派生类 n1 = 10 ...

  9. 大数据学习系列之二 ----- HBase环境搭建(单机)

    引言 在上一篇中搭建了Hadoop的单机环境,这一篇则搭建HBase的单机环境 环境准备 1,服务器选择 阿里云服务器:入门型(按量付费) 操作系统:linux CentOS 6.8 Cpu:1核 内 ...

  10. Java 代码质量

    被滥用的instanceof instanceof滥用, 或者直接强转, 大都数情况可以用方法override, 而且应当避免使用isA(), isB()之类的写法; 比如sonA和sonB都继承自p ...