Stream和Optional

public interface Stream extends BaseStream<T, Stream>

1.1、特性
JAVA8中提出一个集合流的抽象工具(java.util.stream,简称Stream),用于集合内元素的计算,更确切的说是过滤和统计操作。
Stream不是一种真实的数据源(不存在数据结构),所以没有办法直接来创建它,Stream只能依赖其他数据源来转换成我们的抽象操作。Stream本身是不存在,只是抽象出来的一个抽象操作,经过各种操作之后,Stream还需要转换成真实的数据源;
它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程;
Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了。Stream跟迭代器比较,区别:

  • 无存储:Stream是基于数据源的对象,它本身不存储数据元素,而是通过管道将数据源的元素传递给操作。
  • 函数式编程:对Stream的任何修改都不会修改背后的数据源,比如对Stream执行filter操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新的Stream。
  • 延迟执行:Stream的操作由零个或多个中间操作(intermediate operation)和一个结束操作(terminal operation)两部分组成。只有执行了结束操作,Stream定义的中间操作才会依次执行,这就是Stream的延迟特性。
  • 可消费性:Stream只能被“消费”一次,一旦遍历过就会失效。就像容器的迭代器那样,想要再次遍历必须重新生成一个新的Stream

1.2、创建Stream
最常用的创建Stream有两种途径:

  • 通过Stream接口的静态工厂方法;
  • 通过Collection接口的默认方法–stream(),把一个Collection对象转换成Stream;或者使用parallelStream()创建并行
  • 通过Arrays.stream(Object[])方法。
  • BufferedReader.lines()从文件中获得行的流。
  • Files类的操作路径的方法,如list、find、walk等。随机数流Random.ints()。
  • 其它一些类提供了创建流的方法,如BitSet.stream(),
    Pattern.splitAsStream(java.lang.CharSequence), 和
    JarFile.stream()其实最终都是依赖StreamSupport类来完成Stream创建的;
    1.3、常见用法
  • foreach:迭代流中的每个数据
// 使用 forEach 输出了10个随机数
Random random = new Random(100);
random.ints().limit(10).forEach(System.out::println);
  • map:法用于映射每个元素到对应的结果
// 以下代码片段使用 map 输出了元素对应的平方数
List<Integer> list = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> result = list.stream().map(i -> i * i).distinct().collect(Collectors.toList());
System.out.println(list);
System.out.println(result);
  • filter:方法用于通过设置的条件过滤出元素
// 以下代码片段使用 filter 方法过滤出空字符串
List<String> list = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
long count = list.stream().filter(String::isEmpty).count();
System.out.println(count);
  • sorted:用于对流进行排序
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
  • Collectors:实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:
 List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));

6、Optional
是为了解决NPE问题,以往我们需要对对象进行判空:

public String getCity(User user)  throws Exception{
 if(user!=null){
  if(user.getAddress()!=null){
   Address address = user.getAddress();
   if(address.getCity()!=null){
    return address.getCity();
   }
  }
 }
 throw new Excpetion("取值错误"); 
}

而使用Optional之后,代码变成:

public String getCity(User user) throws Exception{
    return Optional.ofNullable(user)
                   .map(u-> u.getAddress())
                   .map(a->a.getCity())
                   .orElseThrow(()->new Exception("取指错误"));
}

Optional(T value)、empty()、of(T value)、ofNullable(T value)

  1. Optional(T value),即构造函数,它是private权限的,不能由外部调用的;
  2. 其余三个函数是public权限;
  3. Optional的本质,就是内部储存了一个真实的值,在构造的时候,就直接判断其值是否为空
发布了45 篇原创文章 · 获赞 6 · 访问量 1804

猜你喜欢

转载自blog.csdn.net/qq_44797965/article/details/104092982