Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
Stream(流)是一个来自数据源的元素队列并支持聚合操作
和以前的Collection操作不同, Stream操作还有两个基础的特征:
在 Java 8 中, 集合接口有两个方法来生成流:
API功能举例
首先创建一个用户的实体类,包括姓名、年龄、性别、地址、赏金 几个属性
@Data
public class User {
//姓名
private String name;
//年龄
private Integer age;
//性别
private Integer sex;
//地址
private String address;
//赏金
private BigDecimal money;
public User(String name, Integer age, Integer sex, String address,BigDecimal money) {
this.name = name;
this.age = age;
this.sex = sex;
this.address = address;
this.money = money;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", money=" + money +
", address='" + address + '\'' +
'}';
}
}
我们在创建一个测试类,包含主方法,并创建一个数据源,作为我们测试的对象
public class Stream {
public static void main(String[] args) {
}
public static List users(){
List list = Arrays.asList(
new User("李星云", 18, 0, "渝州",new BigDecimal(1000)),
new User("陆林轩", 16, 1, "渝州",new BigDecimal(500)),
new User("姬如雪", 17, 1, "幻音坊",new BigDecimal(800)),
new User("袁天罡", 99, 0, "藏兵谷",new BigDecimal(100000)),
new User("张子凡", 19, 0, "天师府",new BigDecimal(900)),
new User("陆佑劫", 45, 0, "不良人",new BigDecimal(600)),
new User("张天师", 48, 0, "天师府",new BigDecimal(1100)),
new User("蚩梦", 18, 1, "万毒窟",new BigDecimal(800))
);
return list;
}
}
api实例
/*filter过滤(T-> boolean)*/
public static void filter(){
List list = users();
List newlist = list.stream().filter(user -> user.getAge() > 20)
.collect(Collectors.toList());
for (User user : newlist) {
System.out.println(user.getName()+" --> "+ user.getAge());
}
}
---结果---
袁天罡 --> 99
陆佑劫 --> 45
张天师 --> 48
/*distinct 去重*/
数据源中复制new User("李星云", 18, 0, "渝州",new BigDecimal(1000)) 并粘贴两个
public static void distinct(){
List list = users();
List newlist = list.stream().distinct().collect(Collectors.toList());
for (User user : newlist) {
System.out.println(user.getName()+" --> "+ user.getAge());
}
}
---结果---
李星云 --> 18
陆林轩 --> 16
姬如雪 --> 17
袁天罡 --> 99
张子凡 --> 19
陆佑劫 --> 45
张天师 --> 48
蚩梦 --> 18
/*sorted排序*/
public static void sorted(){
List list = users();
List newlist = list.stream()
.sorted(Comparator.comparingInt(User::getAge))
.collect(Collectors.toList());
for (User user : newlist) {
System.out.println(user.getName()+" --> "+ user.getAge());
}
}
---结果---
陆林轩 --> 16
姬如雪 --> 17
李星云 --> 18
蚩梦 --> 18
张子凡 --> 19
陆佑劫 --> 45
张天师 --> 48
袁天罡 --> 99
/*limit返回前n个元素*/
public static void limit(){
List list = users();
List newlist = list.stream()
.sorted(Comparator.comparingInt(User::getAge))
.limit(2)
.collect(Collectors.toList());
for (User user : newlist) {
System.out.println(user.getName()+" --> "+ user.getAge());
}
}
---结果---
陆林轩 --> 16
姬如雪 --> 17
/*skip去除前n个元素*/
public static void skip(){
List list = users();
List newlist = list.stream()
.sorted(Comparator.comparingInt(User::getAge))
.skip(2)
.collect(Collectors.toList());
for (User user : newlist) {
System.out.println(user.getName()+" --> "+ user.getAge());
}
}
---结果---
李星云 --> 18
蚩梦 --> 18
张子凡 --> 19
陆佑劫 --> 45
张天师 --> 48
袁天罡 --> 99
/*map(T->R)*/
public static void map(){
List list = users();
List newlist = list.stream()
.map(User::getName).distinct().collect(Collectors.toList());
for (String add : newlist) {
System.out.println(add);
}
}
---结果---
李星云
陆林轩
姬如雪
袁天罡
张子凡
陆佑劫
张天师
蚩梦
/*flatMap(T -> Stream)*/
public static void flatmap(){
List flatmap = new ArrayList<>();
flatmap.add("常宣灵,常昊灵");
flatmap.add("孟婆,判官红,判官蓝");
/*
这里原集合中的数据由逗号分割,使用split进行拆分后,得到的是Stream,
字符串数组组成的流,要使用flatMap的Arrays::stream
将Stream转为Stream,然后把流相连接
*/
flatmap = flatmap.stream()
.map(s -> s.split(","))
.flatMap(Arrays::stream)
.collect(Collectors.toList());
for (String name : flatmap) {
System.out.println(name);
}
}
---结果---
常宣灵
常昊灵
孟婆
判官红
判官蓝
/*allMatch(T->boolean)检测是否全部满足参数行为*/
public static void allMatch(){
List list = users();
boolean flag = list.stream()
.allMatch(user -> user.getAge() >= 17);
System.out.println(flag);
}
---结果---
false
/*anyMatch(T->boolean)检测是否有任意元素满足给定的条件*/
public static void anyMatch(){
List list = users();
boolean flag = list.stream()
.anyMatch(user -> user.getSex() == 1);
System.out.println(flag);
}
---结果---
true
/*noneMatchT->boolean)流中是否有元素匹配给定的 T -> boolean条件*/
public static void noneMatch(){
List list = users();
boolean flag = list.stream()
.noneMatch(user -> user.getAddress().contains("郑州"));
System.out.println(flag);
}
---结果---
true
/*findFirst( ):找到第一个元素*/
public static void findfirst(){
List list = users();
Optional optionalUser = list.stream()
.sorted(Comparator.comparingInt(User::getAge))
.findFirst();
System.out.println(optionalUser.toString());
}
---结果---
Optional[User{name='陆林轩', age=16, sex=1, money=500, address='渝州'}]
/*findAny( ):找到任意一个元素*/
public static void findAny(){
List list = users();
// Optional optionalUser = list.stream()
//// .findAny();
Optional optionalUser = list.stream()
.findAny();
System.out.println(optionalUser.toString());
}
---结果---
Optional[User{name='李星云', age=18, sex=0, money=1000, address='渝州'}]
/*计算总数*/
public static void count(){
List list = users();
long count = list.stream().count();
System.out.println(count);
}
---结果---
8
/*最大值最小值*/
public static void max_min(){
List list = users();
Optional max = list.stream()
.collect(
Collectors.maxBy(
Comparator.comparing(User::getAge)
)
);
Optional min = list.stream()
.collect(
Collectors.minBy(
Comparator.comparing(User::getAge)
)
);
System.out.println("max--> " + max+" min--> "+ min);
}
---结果---
max--> Optional[User{name='袁天罡', age=99, sex=0, money=100000, address='藏兵谷'}] min--> Optional[User{name='陆林轩', age=16, sex=1, money=500, address='渝州'}]
/*求和_平均值*/
public static void sum_avg(){
Listlist = users();
int totalAge = list.stream()
.collect(Collectors.summingInt(User::getAge));
System.out.println("totalAge--> "+ totalAge);
/*获得列表对象金额, 使用reduce聚合函数,实现累加器*/
BigDecimal totalMpney = list.stream()
.map(User::getMoney)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("totalMpney--> " + totalMpney);
double avgAge = list.stream()
.collect(Collectors.averagingInt(User::getAge));
System.out.println("avgAge--> " + avgAge);
}
---结果---
totalAge--> 280
totalMpney--> 105700
avgAge--> 35.0
/*一次性得到元素的个数、总和、最大值、最小值*/
public static void allVlaue(){
List list = users();
IntSummaryStatistics statistics = list.stream()
.collect(Collectors.summarizingInt(User::getAge));
System.out.println(statistics);
}
---结果---
IntSummaryStatistics{count=8, sum=280, min=16, average=35.000000, max=99}
/*拼接*/
public static void join(){
List list = users();
String names = list.stream()
.map(User::getName)
.collect(Collectors.joining(", "));
System.out.println(names);
}
---结果---
李星云, 陆林轩, 姬如雪, 袁天罡, 张子凡, 陆佑劫, 张天师, 蚩梦
/*分组*/
public static void group(){
Map> map = users().stream()
.collect(Collectors.groupingBy(User::getSex));
System.out.println(new Gson().toJson(map));
System.out.println();
Map>> map2 = users().stream()
.collect(Collectors.groupingBy(User::getSex,
Collectors.groupingBy(User::getAge)));
System.out.println(new Gson().toJson(map2));
}
---结果---
{"0":[{"name":"李星云","age":18,"sex":0,"address":"渝州","money":1000},{"name":"袁天罡","age":99,"sex":0,"address":"藏兵谷","money":100000},{"name":"张子凡","age":19,"sex":0,"address":"天师府","money":900},{"name":"陆佑劫","age":45,"sex":0,"address":"不良人","money":600},{"name":"张天师","age":48,"sex":0,"address":"天师府","money":1100}],"1":[{"name":"陆林轩","age":16,"sex":1,"address":"渝州","money":500},{"name":"姬如雪","age":17,"sex":1,"address":"幻音坊","money":800},{"name":"蚩梦","age":18,"sex":1,"address":"万毒窟","money":800}]}
{"0":{"48":[{"name":"张天师","age":48,"sex":0,"address":"天师府","money":1100}],"18":[{"name":"李星云","age":18,"sex":0,"address":"渝州","money":1000}],"19":[{"name":"张子凡","age":19,"sex":0,"address":"天师府","money":900}],"99":[{"name":"袁天罡","age":99,"sex":0,"address":"藏兵谷","money":100000}],"45":[{"name":"陆佑劫","age":45,"sex":0,"address":"不良人","money":600}]},"1":{"16":[{"name":"陆林轩","age":16,"sex":1,"address":"渝州","money":500}],"17":[{"name":"姬如雪","age":17,"sex":1,"address":"幻音坊","money":800}],"18":[{"name":"蚩梦","age":18,"sex":1,"address":"万毒窟","money":800}]}}
/*分组合计*/
public static void groupCount(){
Map num = users().stream()
.collect(Collectors.groupingBy(User::getSex, Collectors.counting()));
System.out.println(num);
Map num2 = users().stream()
.filter(user -> user.getAge()>=18)
.collect(Collectors.groupingBy(User::getSex, Collectors.counting()));
System.out.println(num2);
}
---结果---
{0=5, 1=3}
{0=5, 1=1}
/*分区*/
public static void partitioningBy(){
List list = users();
Map> part = list.stream()
.collect(Collectors.partitioningBy(user -> user.getAge() <= 30));
System.out.println(new Gson().toJson(part));
}
---结果---
{"false":[{"name":"袁天罡","age":99,"sex":0,"address":"藏兵谷","money":100000},{"name":"陆佑劫","age":45,"sex":0,"address":"不良人","money":600},{"name":"张天师","age":48,"sex":0,"address":"天师府","money":1100}],"true":[{"name":"李星云","age":18,"sex":0,"address":"渝州","money":1000},{"name":"陆林轩","age":16,"sex":1,"address":"渝州","money":500},{"name":"姬如雪","age":17,"sex":1,"address":"幻音坊","money":800},{"name":"张子凡","age":19,"sex":0,"address":"天师府","money":900},{"name":"蚩梦","age":18,"sex":1,"address":"万毒窟","money":800}]}