Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
Stream(流)是一个来自数据源的元素队列并支持聚合操作
和以前的Collection操作不同,Stream操作还有两个基础的特征:
| stream of elements +> |filter±> |sorted±> |map±> |collect|
方法名称 | 方法作用 | 方法种类 | 是否支持链式调用 |
---|---|---|---|
count | 统计个数 | 终结方法 | 否 |
forEach | 迭代处理 | 终结方法 | 否 |
filter | 过滤 | 函数拼接 | 是 |
limit | 取用前几个 | 函数拼接 | 是 |
skip | 跳过前几个 | 函数拼接 | 是 |
map | 映射 | 函数拼接 | 是 |
flatMap | 扁平化映射 | 函数拼接 | 是 |
concat | 组合 | 函数拼接 | 是 |
distinct | 去重 | 函数拼接 | 是 |
sorted | 排序 | 函数拼接 | 是 |
peek | 流中调用 | 函数拼接 | 是 |
reduce | 归约操作 | 终结方法 | 否 |
min | 最小值操作 | 终结方法 | 否 |
max | 最大值操作 | 终结方法 | 否 |
anyMatch | 匹配任意元素操作 | 终结方法 | 否 |
allMatch | 匹配所有元素操作 | 终结方法 | 否 |
noneMatch | 没有匹配元素操作 | 终结方法 | 否 |
collect | 集合操作 | 终结方法 | 否 |
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("一往情深");
list.add("石昊");
list.add("秦昊");
list.add("石中天");
// 过滤出名字结尾有“昊”的名字
list.stream().filter(p -> p.endsWith("昊")).forEach(p -> {
System.out.println("符合条件的姓名:" + p);
});
System.out.println("--------------------------------");
// 过滤出名字第一个字有“石”的名字,并且名字长度是3个数
list.stream().filter(p -> p.startsWith("石")).filter(p -> p.length() == 3).forEach(p -> {
System.out.println("符合条件的姓名:" + p);
});
}
}
输出:
符合条件的姓名:石昊
符合条件的姓名:秦昊
--------------------------------
符合条件的姓名:石中天
public class Test {
public static void main(String[] args) {
String str = "一往情深 ,石昊,秦昊,石中天, , 一往情深,AA,aa";
// 1. 按“,”分割成数组
// 2. 去除左右两边空格
// 3. 转小写
// 4. 过滤出不为空的
// 5. 去重
Arrays.stream(str.split(",")).map(String::trim).map(String::toLowerCase).filter(StringUtil::isNotEmpty).distinct().collect(Collectors.toList()).forEach(s -> {
switch (s) {
case "一往情深":
System.out.println("作者:" + s);
break;
case "石昊":
System.out.println("这个就厉害了:" + s);
break;
default:
System.out.println(s);
break;
}
});
}
}
输出:
作者:一往情深
这个就厉害了:石昊
秦昊
石中天
aa
public class Test {
public static void main(String[] args) {
// stream()操作对象示例
List<User> userList = new ArrayList<>();
userList.add(new User(1, "1号选手"));
userList.add(new User(2, "2号选手"));
userList.add(new User(3, "3号选手"));
// 过滤出id大于1的User
System.out.println(userList.stream().filter(p -> p.getId() > 1).collect(Collectors.toList()));
// 1. 按id倒序,从大到小
// 2. 过滤出name中不包含2的User对象
System.out.println(userList.stream().sorted(Comparator.comparing(User::getId).reversed()).filter(p -> !p.getName().contains("2")).collect(Collectors.toList()));
}
}
@Getter
@ToString
class User {
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
}
输出:
[User(id=2, name=2号选手), User(id=3, name=3号选手)]
[User(id=3, name=3号选手), User(id=1, name=1号选手)]
public class test {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 统计
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
}
}
输出:
列表中最大的数 : 7
列表中最小的数 : 2
所有数之和 : 25
平均数 : 3.5714285714285716