Java核心技术卷Ⅱ程序清单1-3

P14-15
程序清单1-3 optional/OptionalTest.java


  1. 代码
  2. 项目结构
  3. 分析
  4. 重要API

1.代码

import java.io.*;
        import java.nio.charset.*;
        import java.nio.file.*;
        import java.util.*;

public class OptionalTest {
    public static void main(String[] args) throws IOException {
    //取出words.txt中所有内容,并将之拆分为单词赋给wordList
        String contents = new String(Files.readAllBytes(Paths.get("src/第1章流库/Words.txt")), StandardCharsets.UTF_8);
        List<String> wordList = Arrays.asList(contents.split("\\PL+"));

    //找到wordList中第一个包含fred字符串的元素并打印
        Optional<String> optionalValue = wordList.stream().filter(s -> s.contains("fred")).findFirst();
        System.out.println(optionalValue.orElse("No word") + " contains fred");

    //创建空Optional并调用orElse输出other(在这里即result)的内容"N/A"
        Optional<String> optionalString = Optional.empty();
        String result = optionalString.orElse("N/A");
        System.out.println("result:" + result);

    //将调用other产生的结果赋给result并打印
        result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());
        System.out.println("result:" + result);

    //调用orElseThrow,在Optional为空时抛出调用exceptionSupplier的结果,并打印异常栈轨迹
        try{
            result = optionalString.orElseThrow(IllegalStateException::new);
            System.out.println("result:" + result);
        }
        catch(Throwable t){
            t.printStackTrace();
        }

    //找到wordList中第一个包含red字符串的元素,如果该元素存在就打印
        optionalValue = wordList.stream().filter(s -> s.contains("red")).findFirst();
        optionalValue.ifPresent(s -> System.out.println(s + " contains red"));

    //创建一个Hashset对象results,将optionalValue里的值(如果值存在的话)传入results
        Set<String> results = new HashSet<>();
        optionalValue.ifPresent(results::add);

    //将Optional的值传入results,并将results::add的返回值(Boolean类型)存入added并打印
        Optional<Boolean> added = optionalValue.map(results::add);
        System.out.println(added);

    //以下请参考“分析”中两个静态方法的部分,以及flatMap API
        System.out.println (inverse(4.0).flatMap(OptionalTest::squareRoot));
        System.out.println (inverse(-1.0).flatMap(OptionalTest::squareRoot));
        System.out.println (inverse(0.0).flatMap(OptionalTest::squareRoot));
        Optional<Double> result2 = Optional.of (-4.0)
                .flatMap (OptionalTest::inverse).flatMap (OptionalTest::squareRoot);
        System.out.println (result2);
    }


    private static Optional<Double> inverse(Double x) {
        return x == 0 ? Optional.empty () : Optional.of (1 / x) ;
    }

    private static Optional<Double> squareRoot(Double x) {
        return x < 0 ? Optional.empty () : Optional.of (Math.sqrt (x));
    }

}

Words.txt里随便写几行字符就好了,这里随便提供一个:

abcdefghijklmnopqrstuvwxyz asd efg hij klm ChineseWordsAreNotAvailable
abcdfredefg
abcdefghijklm!opqrstuvwxyz

2.项目结构

这里写图片描述

3.分析

1.程序目的

演示Optional API的使用方式。

2.代码片段

先讲一下两个静态方法


    private static Optional<Double> inverse(Double x) {
        return x == 0 ? Optional.empty () : Optional.of (1 / x) ;
    }

inverse(Double x)方法:如果传入参数x为0则返回空Optional,不为0则返回具有给定值1/x的Optional


private static Optional<Double> squareRoot(Double x) {
        return x < 0 ? Optional.empty () : Optional.of (Math.sqrt (x));
    }

squareRoot(Double x)方法:如果传入参数x小于0则返回空Optional,不为0则返回具有给定值√x的Optional


回到main函数
(在这里仅分析部分较复杂的代码块)


1st PART:

找到wordList中第一个包含fred字符串的元素并打印,若找不到则打印No word。

Optional<String> optionalValue = wordList.stream()
                            .filter(s -> s.contains("fred")).findFirst();
        System.out.println(optionalValue.orElse("No word") + " contains fred");

stream方法返回用wordList列表创建的流,filter方法返回一个包含旧流中部分元素的新流。这些元素是旧流中包含fred的字符串元素。
findFirst方法返回新流中第一个元素。
orElse方法:产生这个Optional的值,若该Optional为空则产生other(在这里即”No word”)。


2nd PART:

将调用other产生的结果赋给result并打印。

result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());
        System.out.println("result:" + result);

java.util.Locale.getDefault():返回默认区域设置的Java虚拟机实例。
Locale.getDefault().getDisplayName()请参考java.util.Locale.getDisplayName()方法实例


3rd PART:

    //创建一个Hashset对象results,将optionalValue里的值(如果值存在的话)传入results
        Set<String> results = new HashSet<>();
        optionalValue.ifPresent(results::add);

    //将Optional的值传入results,并将results::add的返回值(Boolean类型)存入added并打印
        Optional<Boolean> added = optionalValue.map(results::add);
        System.out.println(added);

有关HashSet请参考Java集合框架系列——HashSet
results::add是将optionalValue中的元素通过add方法传入results中。
optionalValue.map(results::add)尝试将optionalValue中元素传入results,但由于已经被传入过,而HashSet集合不允许重复元素,因而添加不成功。于是results::add返回false,最终打印added得到Optional[false]

4.重要API

java.util.Optional 8


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为空时,抛出调用exceptionSupplier的结果。

void ifPresent(Consumer<? super T> consumer)
如果该Optional不为空,那么就将它的值传递给consumer。

boolean ifPresent()
如果该Optional不为空,则返回true。

<U> Optional<U> map(Function<? super T,? extends U> mapper
产生将该Optional的值传递给mapper后的结果,只要这个Optional不为空且结果不为null,否则产生一个空Optional。

<U> Optional<U> flatmap(Function<? super T,Optional<U>> mapper
产生将mapper应用于当前的Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional。

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。


如有谬误或不完善之处,恳请斧正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值