2-2 Java8的新特性之Stream API

本文详细介绍了Java8中的StreamAPI,包括其作为数据处理的抽象概念,与集合的区别,以及如何实例化Stream(如通过集合、数组、Stream.of()和创建无限流)。文章还深入讨论了Stream的中间操作,如筛选、映射和排序,以及终止操作,如匹配、查找、归约和收集,提供了丰富的代码示例来辅助理解。
摘要由CSDN通过智能技术生成

Stream API

1 简介

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,比如非常复杂的查找、过滤和映射数据等,在使用过程中允许并行执行这些操作。简言之,Stream API 提供了一种 高效且易于使用的处理数据的方式。
Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据结构,关注的是数据的存储,而 Stream 是有关计算的,关注的是数据之间的运算。
注意:

  • Stream 本身是不会存储数据
  • Stream 不会改变源数据,它们会返回一个持有新结果的Stream
  • Stream 操作是延迟进行的,它们是在需要结果的时候才会去执行

Stream 的执行流程

  1. Stream的实例化
  2. 一系列的中间操作(过滤、映射、…)
  3. 终止操作

2 Stream的实例化

从一个数据源(集合、数组)中获取一个流
Stream的实例化常见的有以下三种方式

2.1 通过集合来创建

通过Collection中提供的方法来创建

@Test  
public void test01(){  
List<String> list = new ArrayList<>();  
	//default Stream<E> stream() : 返回一个顺序流  
	Stream<String> stream = list.stream();  
	  
	//default Stream<E> parallelStream() : 返回一个并行流  
	Stream<String> stringStream = list.parallelStream();  
}

2.2 通过数组来创建

通过 Arrays 的静态方法 stream() 可以获取数组流

@Test  
public void test02(){  
	// static <T> Stream<T> stream(T[] array): 返回一个流  
	Stream<String> stream = Arrays.stream(new String[]{"1", "2", "3", "4", "5", "6"});  
}

2.3 通过Stream创建

通过Stream类静态方法 of() 来创建

@Test  
public void test03(){  
	// static<T> Stream<T> of(T... values) : 返回一个流  
	Stream<String> stringStream = Stream.of("1", "2", "3", "4", "5");  
}

2.4 创建无限流

这种方式创建流不是很常见

@Test  
public void test04(){  
	// 迭代  
	// public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)  
	Stream<Integer> stream = Stream.iterate(0, x -> x + 2);  
	stream.limit(10).forEach(System.out::println);  
	// 生成  
	// public static<T> Stream<T> generate(Supplier<T> s)  
	Stream<Double> stream1 = Stream.generate(Math::random);  
	stream1.limit(10).forEach(System.out::println);  
}

3 中间操作

一个中间操作链,对数据源的数据进行处理,如果不执行终止操作,是看不到操作结果的
主要有一下三种类型

3.1 筛选与切片

方法描述
filter(Predicate p)接收Lambda,从流中排除某些元素
distinct()筛选,通过流所生成元素的hashcode()和equals()去除重复元素
limit(long maxSize)截断流,使其元素不超过给定数量
skip(long n)跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
@Test  
public void test05(){  
	List<Student> students = getStudent();  
	// filter(Predicate p) 接收 Lambda , 从流中排除某些元素  
	students.stream().filter(e->e.getScore()>80).forEach(System.out::print);  
	System.out.println();  
	// limit(long maxSize) 截断流,使其元素不超过给定数量  
	students.stream().limit(2).forEach(System.out::print);  
	System.out.println();  
	// skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补  
	students.stream().skip(2).forEach(System.out::print);  
	System.out.println();  
	// distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素  
	students.add(Student.builder().id(5).name("三毛").age(18).score(80.0).build());  
	students.add(Student.builder().id(5).name("三毛").age(18).score(80.0).build());  
	students.stream().distinct().forEach(System.out::print);  
}

3.2 映射

方法描述
map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
@Test  
public void test06(){  
	// map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。  
	List<String> list = Arrays.asList("aa", "bb", "cc", "dd");  
	list.stream().map(String::toUpperCase).forEach(System.out::print);  
	System.out.println();  
	// flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流  
	list.stream().map(StreamTest::getCharacter).forEach(e->e.forEach(System.out::print));  
	System.out.println();  
	list.stream().flatMap(StreamTest::getCharacter).forEach(System.out::print);  
}  
public static Stream<Character> getCharacter(String str){  
	List<Character> characters = new ArrayList<>();  
	for (char c : str.toCharArray()) 
		characters.add(c);  
	return characters.stream();  
}

3.3 排序

方法描述
sorted()产生一个新流,其中按自然顺序排序
sorted(Comparator com)产生一个新流,其中按比较器顺序排序
@Test  
public void test07(){  
	// sorted() 产生一个新流,其中按自然顺序排序  
	List<Integer> list = Arrays.asList(12, 355, 3, 23, -6, 4, 5);  
	list.stream().sorted().forEach(System.out::println);  
	// sorted(Comparator com) 产生一个新流,其中按比较器顺序排序  
	getStudent().stream().sorted(Comparator.comparingInt(Student::getAge)).forEach(System.out::println);  
}

4 终止操作

4.1 匹配和查找

方法描述
allMatch(Predicate p)检查是否匹配所有元素
anyMatch(Predicate p)检查是否至少匹配一个元素
noneMatch(Predicate p)检查是否没有匹配所有元素
findFirst()返回第一个元素
findAny()返回当前流中的任意元素
count()返回流中元素总数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值
forEach(Consumer c)内部迭代
@Test  
public void test08(){  
	List<Student> student = getStudent();  
	// allMatch(Predicate p) 检查是否匹配所有元素  
	System.out.println(student.stream().allMatch(e -> e.getAge() > 18)); // 检查学生年龄是否都大于18岁  
	// anyMatch(Predicate p) 检查是否至少匹配一个元素  
	System.out.println(student.stream().anyMatch(e -> e.getAge() < 18)); // 检查学生年龄是否有小于18岁的  
	// noneMatch(Predicate p) 检查是否没有匹配所有元素  
	System.out.println(student.stream().noneMatch(e -> e.getAge() < 9)); // 检查学生年龄是否都不小于9岁  
	// findFirst() 返回第一个元素  
	System.out.println(student.stream().findFirst());  
	// findAny() 返回当前流中的任意元素  
	System.out.println(student.stream().findAny());  
	// count() 返回流中元素总数  
	System.out.println(student.stream().count());  
	// max(Comparator c) 返回流中最大值  
	System.out.println(student.stream().max(Comparator.comparingInt(Student::getAge)));  
	// min(Comparator c) 返回流中最小值  
	System.out.println(student.stream().min(Comparator.comparingInt(Student::getAge)));  
	// forEach(Consumer c) 内部迭代  
	student.stream().forEach(System.out::println);  
}

4.2 归约

方法描述
reduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 Optional
@Test  
public void test09(){  
	// reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T identity 这是一个附加值  
	System.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().reduce(0, Integer::sum)); // 计算1——9的总和  
	// reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 OptionalSystem.out.println(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().reduce(Integer::sum));  
}

4.3 收集

方法描述
collect(Collector c)将流转换为其他形式。接收一个 Collector 接口的实现,用于给Stream中元素做汇总的方法
@Test  
public void test10(){  
	// collect(Collector c) 将流转换为其他形式。接收一个 Collector 接口的实现,用于给Stream中元素做汇总的方法  
	List<Student> student = getStudent();  
	// 查找分数大于80的学生,结果返回一个List集合  
	List<Student> collect = student.stream().filter(e -> e.getScore() > 80).collect(Collectors.toList());  
	collect.forEach(System.out::println);  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启航zpyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值