Stream

作者: 一只有思想的小蚂蚁 | 来源:发表于2021-08-02 17:39 被阅读0次

一、Stream简介
在使用集合类时,一个通用的模式是在集合上进行迭代,然后处理返回的每一个元素。
使用 for 循环计算来自伦敦的艺术家人数:

int count = 0;
for (Artist artist : allArtists) {
    if (artist.isFrom("London")) { 
        count++; 
    } 
}

以上是采用外部迭代的方式,Java8以后可以采用内部迭代的方式。
使用内部迭代计算来自伦敦的艺术家人数:

long count = 
    allArtists.stream() 
              .filter(artist -> artist.isFrom("London")) 
              .count();

Stream:是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列,是用函数式编程方式在集合类上进行复杂操作的工具。
Stream的特点:
Stream自己不会存储元素
Stream不会改变源对象,相反,它们会返回一个持有结果的新Stream
Stream操作时延迟执行的,这意味着它们会等到需要结果的时候才执行

以上整个过程被分解为两种更简单的操作:过滤和计数,两种操作只需对艺术家列表迭代一次。
最终不产生新集合的方法叫作惰性求值方法;最终会从 Stream 产生值的方法叫作及早求值方法。判断一个操作是惰性求值还是及早求值很简单:只需看它的返回值。如果返回值是 Stream, 那么是惰性求值;如果返回值是另一个值或为空,那么就是及早求值。使用这些操作的理想方式就是形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果,这正是它的合理之处。

二、获取Stream的方式:
1.通过集合
Collection接口提供了两个获取流的方法
default Stream<E> stream():返回一个顺序流
default Stream<E> parallelStream():返回一个并行流
2.通过数组
Arrays的静态方法stream()可以获取数组流
static<T> Stream<T> stream(T[] array):返回一个流
重载形式,能够处理对应基本类型的数组:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)
3.通过Stream的of方法
三、Stream的API

  1. filter
Stream<T> filter(Predicate<? super T> predicate);
//接收Predicate接口,从流中排除某些元素,返回符合条件的流元素组成的流。

遍历数据并检查其中的元素时,可尝试使用 Stream 中提供的新方法 filter,获取首字母为数字的字符串:

List<String> beginningWithNumbers = 
                  Stream.of("a", "1abc", "abc1") 
                  .filter(value -> isDigit(value.charAt(0)))
                  .collect(toList());
  1. map
<R> Stream<R> map(Function<? super T, ? extends R> mapper);

如果有一个函数可以将一种类型的值转换成另外一种类型,map 操作就可以使用该函数,将一个流中的值转换成一个新的流。使用 map 操作将字符串转换为大写形式:

List<String> collected = 
                Stream.of("a", "b", "hello") 
                .map(string -> string.toUpperCase()) 
                .collect(toList());
  1. flatMap
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

flatMap 方法可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream。包含多个列表的 Stream:

List<Integer> together = 
        Stream.of(asList(1, 2), asList(3, 4)) 
        .flatMap(numbers -> numbers.stream()) 
        .collect(toList());

也可以将map和flatMap理解为ArrayList中的add方法和addAll方法。

ArrayList list1 = new ArrayList();
list1.add(1);
 list1.add(2);
list1.add(3);

ArrayList list2 = new ArrayList();
list2.add(4);
list2.add(5);
 list2.add(6);

list1.add(list2);
System.out.println(list1);

list1.addAll(list2);
System.out.println(list1);
  1. distinct
Stream<T> distinct();
//筛选,通过流所生成元素的hashCode()和equals()去除重复元素
  1. sorted
Stream<T> sorted();//自然排序
Stream<T> sorted(Comparator<? super T> comparator);//定制排序
  1. collect(toList())
    collect(Collector c) 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法Collector接口中方法的实现决定了如何对流执行收集的操作(如收集到List、Set、Map)另外,Collections实用类提供了很多静态方法,可以方便地创建常见收集器实例。
List<String> collected = Stream.of("a", "b", "c") .collect(Collectors.toList()); 
  1. reduce
    reduce(T identity,BinaryOperator)可以将流中的元素反复结合起来,得到一个值。
    举例:
    List<Integer> list = Arrays.asList(1,2,3,4,5);
    list.stream().reduce(0,Integer::sum);

reduce(BinaryOperator) 可以将流中元素反复结合起来,得到一个值,返回Optional

    List<Enplyee> employees = EmployeeData.getEmployees();
    Stream<Double> salaryStream = employees.stream().map(Employee::getSalary);
    salaryStream.reduce(Double::sum);

8.其他方法
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流中元素的总个数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值

相关文章

网友评论

      本文标题:Stream

      本文链接:https://www.haomeiwen.com/subject/bczneltx.html