详解Java8 Optional类{最全}
1:Optional
1.1 概述
Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException),提供了一些的方法代替过去的if-else处理逻辑,并与Stream流结合提供一致性的函数式编程.
注意: Optional 不支持Java本身提供的序列化与反序列化机制,也就是RPC不能使用Java提供的序列化机制
1.2 方法概览
页面 看不清,请下载或者另一个页面打开即可看清楚
2: 常用方法
2.1 构造方法
- 需要提前检查NPE 使用of方法
- 不管情况直接构造 使用ofNULLable*()方法
- empty() 方法 前面方法间接使用了这个方法
@Test(expected = NoSuchElementException.class) public void whenCreateEmptyOptional_thenNull() { Optional<User> emptyOpt = Optional.empty(); emptyOpt.get();// 没有值 将会抛出异常 } @Test(expected = NullPointerException.class) public void test_of() { User user=null; Optional<User> optional = Optional.of(user); } @Test public void test_ofNuLLAble() { User user=null; Optional<User> optional = Optional.ofNullable(user); optional.orElse(new User()); // 一般不使用 optional.get(); }
2.2 取得值
- get方法取不到值将会抛出异常NPE
- orElse系列方法,在null值的情况 将会提供默认值
// 取得值 @Test public void test_getValue() { Optional<String> opt = Optional.ofNullable(null); String str = opt.get(); String str2 = opt.orElse("Tom"); Assert.assertEquals("Tom", str2); String str3 = opt.orElseGet(()->"Tom2"); Assert.assertEquals("Tom2", str3); }
2.3 检查处理
// 检查处理 @Test public void test_Check() { Optional<String> opt = Optional.ofNullable(null); Assert.assertTrue(opt.isEmpty()); Assert.assertFalse(opt.isPresent());//not null if(opt.isPresent()) { String string = opt.get().toUpperCase(); } opt.ifPresent(x->x.toUpperCase()); //解决了if 问题 代码简洁 // 内部是runable 不能返回值 所以值这个方法功能有限 但是可以执行一些耗时操作 opt.ifPresentOrElse(x->x.toUpperCase(),()->System.out.println("sss")); }
2.4 返回值
@Test public void test_returnValue() { Optional<String> opt = Optional.ofNullable(null); Assert.assertEquals("Cat", opt.orElse("Cat")); Assert.assertEquals("Cat", opt.orElseGet(()->"Cat")); // or 为jdk9 新方法 String str_tom = opt.or(()->Optional.of("Tom")).get(); Assert.assertEquals("Tom", str_tom); }
2.5 返回异常
@Test(expected = NoSuchElementException.class) public void test_return_Exception() { Optional<String> opt = Optional.ofNullable(null); Assert.assertEquals("Cat", opt.orElseThrow()); Assert.assertEquals("Cat", opt.orElseThrow(()->new NoSuchElementException())); }
2.6 转换 与过滤
@Test public void test_MapAndFilter() { String [] str= new String[] {"a","b","c","d","1"}; Optional<String[]> opt = Optional.ofNullable(str); // filter String[] res = opt.filter(x->{ for (String s : x) { if(s.contains("e")) { return false; } } return true; }).get(); System.out.println(Arrays.toString(res)); // map 转大小 List<String> list=new ArrayList<>(); for(String x:str) {list.add(x);}; Optional<String> map = Optional.ofNullable(list).map(x->x.iterator().next().toUpperCase()); List<String> list2 = Optional.ofNullable(list).stream(). flatMap(x->x.stream().map(y->y.toUpperCase())).collect(Collectors.toList()); System.out.println(list2); }
2.7 链式操作
- 支持链式操作,序列化滞后
@Test public void Test_ChainCollec() { Street street = new Street("武汉轻工大学", 5); Address address = new Address(street); Person person = new Person("Tom", 12,address ); String string = Optional.ofNullable(person). flatMap(u->u.getAddress()) .flatMap(p->p.getStreet()) .map(l->l.getStreetName()) .orElse("default"); System.out.println(string); Address address2 = new Address(null); Person person2 = new Person("Tom", 12,null); String s3 = Optional.ofNullable(person2).flatMap(u->u.getAddress()) .orElse(new Address(null)) .getStreet() .orElse(new Street("武汉大学", 1)) .getStreetName(); System.out.println(s3); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream obr; try { obr = new ObjectOutputStream(bos); obr.writeObject(person); } catch (IOException e) { e.printStackTrace(); } ByteArrayInputStream inputStream = new ByteArrayInputStream(bos.toByteArray()); try { ObjectInputStream inputStream2 = new ObjectInputStream(inputStream); Person person23 = (Person) inputStream2.readObject(); System.out.println(person23.getAddress().get().getStreet().get().getStreetName()); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
其他代码
class Person implements Serializable{ private String name; private Integer age; private Address address; public Person(String name, Integer age, Address address) { this.name = name; this.age = age; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Optional<Address> getAddress() { return Optional.ofNullable(this.address); } public void setAddress(Address address) { this.address = address; } } class Address implements Serializable{ private Street street ; public Optional<Street> getStreet() { return Optional.ofNullable(this.street); } public void setStreet(Street street) { this.street = street; } public Address(Street street) { super(); this.street = street; } } class Street implements Serializable{ private String streetName ; private Integer streetNo; public Street(String streetName, Integer streetNo) { this.streetName = streetName; this.streetNo = streetNo; } public String getStreetName() { return streetName; } public void setStreetName(String streetName) { this.streetName = streetName; } public Integer getStreetNo() { return streetNo; } public void setStreetNo(Integer streetNo) { this.streetNo = streetNo; } }