利用java8新特性,可以用简洁高效的代码来实现一些数据处理。
定义1个Apple对象:
public class Fruit {
private Integer id;
private String name;
private BigDecimal money;
private Integer num;
public Fruit(Integer id, String name, BigDecimal money, Integer num) {
this.id = id;
this.name = name;
this.money = money;
this.num = num;
}
}
添加一些测试数据:
//存放Fruit对象集合
List<Fruit> fruitList = new ArrayList<>();
Fruit fruit1 = new Fruit(1,"苹果1",new BigDecimal("3.25"),10);
Fruit fruit2 = new Fruit(1,"苹果2",new BigDecimal("1.35"),20);
Fruit fruit3 = new Fruit(2,"香蕉",new BigDecimal("2.89"),30);
Fruit fruit4 = new Fruit(3,"荔枝",new BigDecimal("9.99"),40);
fruitList.add(fruit1);
fruitList.add(fruit2);
fruitList.add(fruit3);
fruitList.add(fruit4);
1、分组
List里面的对象元素,以某个属性来分组,例如,以id分组,将id相同的放在一起:
//List 以ID分组 Map<Integer,List<Fruit>>
Map<Integer, List<Fruit>> groupBy = fruitList.stream().collect(Collectors.groupingBy(Fruit::getId));
System.out.println("groupBy:"+groupBy);
//{1=[Fruit{id=1, name='苹果1', money=3.25, num=10}, Fruit{id=1, name='苹果2', money=1.35, num=20}], 2=[Fruit{id=2, name='香蕉', money=2.89, num=30}], 3=[Fruit{id=3, name='荔枝', money=9.99, num=40}]}
2、List转Map
id为key,apple对象为value,可以这么做:
/**
* List -> Map
* 需要注意的是:
* toMap 如果集合对象有重复的key,会报错Duplicate key ....
* apple1,apple12的id都为1。
* 可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
*/
Map<Integer, Fruit> fruitMap = fruitList.stream().collect(Collectors.toMap(Fruit::getId, a -> a,(k1,k2)->k1));
// {1=Fruit{id=1, name='苹果1', money=3.25, num=10}, 2=Fruit{id=2, name='香蕉', money=2.89, num=30}, 3=Fruit{id=3, name='荔枝', money=9.99, num=40}}
3、过滤Filter
从集合中过滤出来符合条件的元素:
//过滤出符合条件的数据
List<Fruit> filterList = fruitList.stream().filter(a -> a.getName().equals("香蕉")).collect(Collectors.toList());
// [Fruit{id=2, name='香蕉', money=2.89, num=30}]
4、求和
将集合中的数据按照某个属性求和:
//计算 总金额
BigDecimal totalMoney = fruitList.stream().map(Fruit::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
System.err.println("totalMoney:"+totalMoney); //totalMoney:17.48
5、去重
// 根据id去重
List<Fruit> unique = fruitList.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(comparingLong(Fruit::getId))), ArrayList::new)
);
Collectors类常用的静态工厂方法:
工厂方法 | 返回类型 | 用于 | 示例 |
toList |
| 把流中所有项目收集到一个List |
|
toSet |
| 把流中所有项目收集到一个Set,删除重复项 |
|
toCollection |
| 把流中所有项目收集到给定的供应源创建的集合 |
|
counting |
| 计算流中元素的个数 |
|
summingInt |
| 对流中项目的一个整数属性求和 |
|
averagingInt |
| 计算流中项目Integer属性的平均值 |
|
summarizingInt |
| 收集美于流中項目Integer 属性的統竍値,例如最大、最小、总和与平均値 |
|
joining |
| 连接对流中毎个項目调用toString方法所生成的字符串 |
|
maxBy |
| 一个包裹了流中按照给定比较器选出的最大元素的Optional,或如果流为空则为optional.empty() |
|
minBy |
| 一个包裹了流中按照给定比较器选出的最小元素的Optional,或如果流为空则为optional.empty() |
|
reducing | 归约操作产生的类型 | 从一个作为累加器的初始値幵始,利用BinaryOperator与流中的元素逐个结合,从而将流归约为单个值 |
|
collectingAndThen | 转换函数的类型 | 包裹另一个收集器,对其结果应用转换函数 |
|
groupingBy |
| 根据项目的一个属性的值对流中的项目作问组,并将属性值作为结果Map的键 |
|
mapping | 是一个收集器,可以传入两个函数, 一个函数对流中的元素做变换,另一个则将变换的结果对象收集起来 ,目的是在累加之前对每个元素应用一个映射函数 |
| |
partitioningBy |
| 相据对流由每个顶日应田谓词的结里求对顶日井行分区 |
|