概述
作用:处理 数组 或 集合 数据
一、创建
- 对于集合:通过集合的
stream()
方法
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();
- 对于数组:通过数组的
Arrays.stream()
方法
// int[] arr = {1, 2, 3, 4, 5}; // 这是错误的, Integer[] arr... 才是对的 这不是重点 中间操作链和终止操作才是重点
Integer[] arr = {1, 2, 3, 4, 5}
Stream<Integer> stream = Arrays.stream(arr);
// 对于 int 数组
int[] arr = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(arr);
- 通过静态方法
Stream.of()
Stream<String> stream = Stream.of("apple", "banana", "orange");
- 双列集合转化成 Stream 流: 先转成单列集合再转化
map 的 entrySet 方法可以理解为是将 map 转化为 对象的集合, 一个键值对 对应一个对象, 比如, 下面例子中:
entrySet 变量中包含的是 3 个对象, 对象 1 的有个属性是蜡笔小新, 属性对应的值是 19, 对象 2 有个属性名为日向翔阳, 属性值是 16
Map<String,Integer> map = new HashMap<>();
map.put("蜡笔小新",19);
map.put("黑子",17);
map.put("日向翔阳",16);
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
entrySet.stream().var
二、中间操作链
经过中间操作后,都是返回一个新的 Stream
-
filter(Predicate<T> predicate)
:根据给定的条件(Predicate)筛选出符合条件的元素,并返回一个新的 Stream。 -
map(Function<T, R> mapper)
:将 Stream 中的每个元素通过给定的映射函数(Function)进行转换,返回一个新的 Stream,新 Stream 中的元素类型为映射后的类型。除了映射功能,还有计算功能。 -
flatMap(Function<T, Stream<R>> mapper)
:将 Stream 中的每个元素映射成一个新的 Stream,并将所有新的 Stream 合并成一个新的 Stream。 -
distinct()
:去除 Stream 中重复的元素,得到一个去重后的新的 Stream。 -
sorted()
:对 Stream 中的元素进行排序,默认是降序。 -
sorted(Comparator<T> comparator)
:对 Stream 中的元素进行排序,使用自定义的比较器(Comparator)进行排序。 -
limit(long maxSize)
:截取 Stream 中的前maxSize
个元素,返回一个新的 Stream。 -
skip(long n)
:跳过 Stream 中的前n
个元素,返回一个新的 Stream。 -
peek(Consumer<T> action)
:对 Stream 中的每个元素进行操作,但是不改变 Stream 的内容,返回一个新的 Stream。
StreamAPI 的 debug的使用
先在stream()
处打断点,运行调试
再“跟踪当前流链”
map 和 flatMap 的区别
相同点: 都是将一个流转化为其他形式的流, 比如, 将 author 流转化为 Integer 流(map), 将 author 流转化为 book 流(flatmap)
不同点:
map 是一对一
flatMap 是一对多, 使用情况, 举个例子:
现在有一个 author 流, Author.java 长这样, 可以看到, author 里包含列表, 这是重点, 这里可能说的含糊不清, 需要自己体会; author 和 book 是一对多的, 所以可以使用 flatmap 转化
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode//用于后期的去重使用
public class Author implements Comparable<Author>{
//id
private Long id;
//姓名
private String name;
//年龄
private Integer age;
//简介
private String intro;
//作品
private List<Book> books;
@Override
public int compareTo(Author o) {
return o.getAge()-this.getAge();
}
}
// 把 Author 流转化成 String 流,-> 后接的是基本数据类型的东西
authors.stream()
.map(author -> author.getName())
.forEach(name -> sout(name));
// 把 Author 流转化成 Book 流, -> 后接的是集合或者数组的 Stream
authors.stream()
.flatmap(author -> author.getBooks().stream) // 得到一个 Book 的 stream
.flatMap(book -> Arrays.stream(book.getCategory().split(",")))
.forEach(category -> sout(category));
打印所有数据的所有分类。不能出现这种格式:哲学,爱情 爱情
分析:因为分类在 author 的 books 的 categroy ,author 里的 books 是 List 类型的,books 的 category 又以逗号隔开,可以用 split()
将其分割成数组
看这个就比较清晰
以下是 map 示例
三、终止操作
-
forEach(Consumer<T> action)
:对流中的每个元素执行给定的操作。 -
count()
:返回流中的元素个数。 -
collect(Collector<? super T, A, R> collector)
:将流中的元素收集到一个集合或者数据结构中,如List, Set, Map 等, 如:.collect(Collectors.toList())
。 -
toArray()
:将流中的元素转换为一个数组。 -
findFirst()
:返回流中的第一个元素(如果存在), 返回一个 Optional。 -
findAny()
:返回流中的任意一个元素(如果存在), 返回一个 Optional。 -
min(Comparator<? super T> comparator)
:返回流中的最小元素,使用自定义比较器, 返回一个 Optional。 -
max(Comparator<? super T> comparator)
:返回流中的最大元素,使用自定义比较器, 返回一个 Optional。 -
allMatch(Predicate<? super T> predicate)
:检查流中的所有元素是否都满足给定条件, 返回 boolean。 -
anyMatch(Predicate<? super T> predicate)
:检查流中是否有任意一个元素满足给定条件, 返回 boolean。 -
noneMatch(Predicate<? super T> predicate)
:检查流中是否没有任何元素满足给定条件, 返回 boolean。 -
reduce(BinaryOperator<T> accumulator)
:将流中的元素依次执行二元操作,返回一个合并后的结果。TODO -
reduce(T identity, BinaryOperator<T> accumulator)
:将流中的元素依次执行二元操作,并附带一个初始值,返回一个合并后的结果。 -
reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
:将流中的元素进行转换,然后执行二元操作,并附带一个初始值,返回一个合并后的结果。