Java 的 Stream 流
- 引出 Stream 流
- 传统方式操作集合数据
- Stream 流操作集合数据
- Stream 流的常用 API
- 获取 Stream 流的两种方式
- Stream 流的注意事项
- forEach()
- count()
- filter()
- limit()
- skip()
- map()
- sorted()
- distinct()
- match()
- find()
- reduce()
- 统计集合中某一元素出现的次数
- concat()
- 收集流中中的数据到集合中 collect()
引出 Stream 流
传统方式操作集合数据
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Hello {
public static void main(String[] args) {
// 一个 ArrayList 集合中存储有以下数据:张无忌、周芷若、赵敏、张强、张三丰
// 需求:拿到所有姓张的、拿到名字长度为三个字的、打印这些数据
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 拿到所有姓张的、拿到名字长度为三个字的
List<String> nameZ = new ArrayList<String>();
for (String string : list) {
if (string.startsWith("张") && string.length() == 3) {
nameZ.add(string);
System.out.println(string);
}
}
}
}
Stream 流操作集合数据
public class Hello {
public static void main(String[] args) {
// 一个 ArrayList 集合中存储有以下数据:张无忌、周芷若、赵敏、张强、张三丰
// 需求:拿到所有姓张的、拿到名字长度为三个字的、打印这些数据
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// stream 流操作集合
list.stream().filter(s -> s.startsWith("张")) // 拿到所有姓张的
.filter(s -> s.length() == 3) // 拿到名字长度为三个字的
.forEach(s -> System.out.println(s)); // 打印这些数据
}
}
# 可以看到 stream 流的代码更简洁、可读性更强、由于 stream 流是在原来的集合上操作
# 不需要创建新的集合、因而代码的执行效率更高
Stream 流的常用 API
获取 Stream 流的两种方式
public class Hello {
public static void main(String[] args) {
// 方式一
// Collection 集合中的默认方法 default Stream<E> stream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
// 方式二
// Stream 中的静态方法 of(T ...values) 获取流
Stream<String> strs = Stream.of("1", "2", "3");
strs.forEach(s -> System.out.println(s));
}
}
Stream 流的注意事项
- Stream 流只能操作一次
- Stream 方法返回的是新的流
- Stream 不调用终结方法、中间的操作不会执行
forEach()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3");
// forEach 遍历集合中的数据
// void forEach(Consumer<? super T> action);
list.stream().forEach(s -> System.out.println(s));
// lambda 可以转换成方法引用
// 引用 打印流的方法 println() 重写 Consumer 接口中的 accept() 方法
list.stream().forEach(System.out :: println);
}
}
count()
// 统计集合中元素个数
// long count();
long count = list.stream().count();
System.out.println(count); // 3
filter()
// filter() 方法过滤出符合条件的数据
// Stream<T> filter(Predicate<? super T> predicate);
list.stream().filter(s -> s.length() == 1) //
.forEach(s -> System.out.println(s));
limit()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3");
// limit(n) 方法 截取流的前 n 个元素
// Stream<T> limit(long maxSize);
list.stream().limit(2) //
.forEach(s -> System.out.println(s)); // 1, 2
}
}
skip()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3");
// skip(n) 方法 跳过流中前 n 个数据
// Stream<T> skip(long n);
list.stream().skip(2).forEach(s -> System.out.println(s)); // 3
}
}
map()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3");
// map() 将一种类型转换为另一种类型
// <R> Stream<R> map(Function<? super T, ? extends R> mapper);
list.stream().map(s -> Integer.parseInt(s)) //
.forEach(s -> System.out.println(s));
}
}
sorted()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3");
// sorted() 对数组中的元素进行自然排序
// Stream<T> sorted();
list.stream().sorted().forEach(s -> System.out.println(s));
// 按某种规则对数组元素进行排序
// Stream<T> sorted(Comparator<? super T> comparator);
// int compare(T o1, T o2);
list.stream().sorted(Hello::compare).forEach(s -> System.out.println(s));
}
private static int compare(String a, String b) {
return a.hashCode() - b.hashCode();
}
}
distinct()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "1");
// distinct() 去除重复元素
// Stream<T> distinct();
list.stream().distinct().forEach(s -> System.out.println(s));
}
}
match()
- allMatch() 匹配所有元素、所有元素都需要满足条件
- anyMatch() 匹配某个元素、只要有一个元素满足条件即可
- noneMatch() 匹配所有元素、所有元素都不满足条件
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "1");
// boolean allMatch(Predicate<? super T> predicate);
// 所有的元素都大于 0 吗?true
System.out.println(list.stream().allMatch(s -> Integer.parseInt(s) > 0));
// boolean anyMatch(Predicate<? super T> predicate);
// 流中有大于 3 的元素吗?false
System.out.println(list.stream().anyMatch(s -> Integer.parseInt(s) > 3));
// boolean noneMatch(Predicate<? super T> predicate);
// 所有元素都不大与(小于等于) 2 吗?// false
System.out.println(list.stream().noneMatch(s -> Integer.parseInt(s) > 2));
}
}
find()
- findAny()
- findFirst()
// findFirst() 返回查找到的第一个元素
System.out.println(list.stream().findFirst().get());
reduce()
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "1");
// T reduce(T identity, BinaryOperator<T> accumulator);
// identity: 默认值
// 参数二:计算规则
// reduce() 对流中的数据进行计算
// 01231
System.out.println(list.stream().reduce("0", (s1, s2) -> s1 + s2));
}
}
统计集合中某一元素出现的次数
public class Hello {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "1");
// 统计集合中 1 出现的次数
Integer sum = list.stream() //
.map((s) -> Integer.parseInt(s) == 1 ? 1 : 0) //
.reduce((x, y) -> x + y).get(); //
System.out.println(sum); // 2
}
}
concat()
// public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
// 将两个流合并为一个流
// Stream.concat(a, b)
收集流中中的数据到集合中 collect()
public class Hello {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5);
// 收集数据到List集合中 collect
// 参数 :
// Collectors.toList()
// Collectors.toSet()
// Collectors.toMap()
List<Integer> collect = list.stream().filter(i -> i >= 3) //
.collect(Collectors.toList());
collect.stream().forEach(s -> System.out.println(s)); // 3 4 5
}
}
未完、待续…