一、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
- 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());
- 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());
- 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);
- distinct
Stream<T> distinct();
//筛选,通过流所生成元素的hashCode()和equals()去除重复元素
- sorted
Stream<T> sorted();//自然排序
Stream<T> sorted(Comparator<? super T> comparator);//定制排序
- collect(toList())
collect(Collector c) 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法Collector接口中方法的实现决定了如何对流执行收集的操作(如收集到List、Set、Map)另外,Collections实用类提供了很多静态方法,可以方便地创建常见收集器实例。
List<String> collected = Stream.of("a", "b", "c") .collect(Collectors.toList());
- 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)返回流中最小值
网友评论