平时写代码的时候,经常会对list进行操作,自从1.8之后有了stream 。能使用的话,就经常使用了,现在在这归总一下经常使用的几个stream的API。
为了方便下边理解,创建两个实体类和一个list
/**
* 交易实体类
*/
public class Transaction {
//id
private Integer id;
//货币
private Currency currency;
//金额
private Double money;
//-------省略 getter和setter--------
}
/**
* 货币
*/
public class Currency {
private Integer id;
private String name;
//-------省略 getter和setter--------
}
//----------------------init-----------------------
List<Transaction> transactions = Arrays.asList(new Transaction(1,new Currency(1,"人民币"),22.22),
new Transaction(2,new Currency(2,"美元"),30.21),
new Transaction(3,new Currency(2,"美元"),29.22),
new Transaction(4,new Currency(2,"美元"),18.22),
new Transaction(5,new Currency(1,"人民币"),15.5));
- stream filter
- filter 过滤 筛选
- filter 中传参的是 Predicate
- Predicate这个接口是一个函数型接口,
- 该接口通俗理解的话,是为了支持lambda而生的,1.8之后才有。
- jdk提供的简单来说只有三个函数型接口:
- Predicate:返回boolean
- Consumer:没有返回值
- Function:返回一个对象类型
- 玩lambda,一定要记住这三个接口。
@Test
public void test1(){
//转换成一个新的list
List<Transaction> filterList = transactions.stream().filter(t -> t.getMoney() > 20).collect(Collectors.toList());
//满足条件的循环处理
transactions.stream().filter(t -> t.getMoney() > 20).forEach(System.out::println);
}
- stream groupingBy
- groupingBy 分组
- groupingBy 中无论是传 Transaction::getCurrency 还是 t->t.getCurrency() 都是根据currency来分组的意思, 这样能得到一个
- key为currency value 为 transaction 的map。(分组需要 equals和hashCode 都相等才能分为一组)
@Test
public void test2(){
Map<Currency, List<Transaction>> currencyListMap = transactions.stream().collect(Collectors.groupingBy(Transaction::getCurrency));
Map<Currency, List<Transaction>> currencyListMap1 = transactions.stream().collect(Collectors.groupingBy(t->t.getCurrency()));
}
- stream distinct
- distinct:去重,
- 同理 只有引用对象的 equals&&hashCode 都相等时 才去重。
@Test
public void test3(){
transactions.stream().filter(t -> t.getMoney()>20)
.distinct()
.forEach(System.out::println);
}
-
stream limit和skip
- limit 与 skip 互补,一个是从前截断,一个是跳过前边
@Test
public void test4(){
transactions.stream()
.limit(2)
.forEach(System.out::println);
transactions.stream()
.skip(2)
.forEach(System.out::println);
}
- stream map
- map 方法,改变一个类型
@Test
public void test5(){
List<Currency> collect = transactions.stream()
.map(Transaction::getCurrency)
.collect(toList());
collect.forEach(System.out::println);
transactions.stream()
.map(Transaction::getMoney)
.forEach(System.out::println);
}
-
stream match
- allMatch:是否全部匹配
- anyMatch:是否最少有一个匹配
- noneMatch:是否全部都不匹配
@Test
public void test6(){
boolean b = transactions.stream()
.allMatch(t -> t.getMoney()<20);
System.out.println(b);
boolean b1 = transactions.stream()
.anyMatch(t -> t.getMoney() < 20);
System.out.println(b1);
boolean b2 = transactions.stream()
.noneMatch(t -> t.getMoney() < 20);
System.out.println(b2);
}
-
stream findFirst
- findFirst:返回第一个元素 optional类型
- findAny:返回一个元素
- 区别在于 findAny在并行上做的更好。
@Test
public void test7(){
transactions.stream()
.findFirst()
.ifPresent(System.out::println);
transactions.stream()
.findAny()
.ifPresent(System.out::println);
}
-
stream reduce
- 归纳,
- 算和或者算积,最大值,最小值 等等。。
- 如果没有初始值, 则返回Optional对象
@Test
public void test8(){
//求和
transactions.stream()
.map(Transaction::getMoney)
.reduce(Double::sum)
.ifPresent(System.out::println);
//求积
transactions.stream()
.map(Transaction::getMoney)
.reduce( (a, b) -> a * b)
.ifPresent(System.out::println);
}
- stream count
- 一共有多少个元素
@Test
public void test9(){
long count = transactions.stream()
.count();
System.out.println(count);
}
- stream collect
- 以,分隔 连接字符串
@Test
public void test10(){
String collect = transactions.stream().map(t -> t.getCurrency().getName()).distinct().collect(joining(","));
System.out.println(collect);
}
- 查询平均值,求和
@Test
public void test11(){
Double avg = transactions.stream().collect(Collectors.averagingDouble(Transaction::getMoney));
System.out.println(avg);
Double sum = transactions.stream().collect(Collectors.summingDouble(Transaction::getMoney));
System.out.println(sum);
}
- list 转为 map
- key为id。value为原对象
@Test
public void test12(){
Map<Integer, Transaction> collect = transactions.stream().collect(Collectors.toMap(Transaction::getId, t -> t));
System.out.println(collect);
}