关于java8 lambdar使用小记
几个小需求:
- 找出XX市到XX市XX车型XX车长,运输记录中出现最多次的运价。如果有多个价格,并且出现的次数相同,则运价取0
- 找出XX市到XX市XX车型XX车长,运输记录中的最高价 并且获取出最高价与产生该价格的时间
- 找出XX市到XX市XX车型XX车长,运输记录中的最低价 并且获取出最低价与产生该价格的时间
- 求出XX市到XX市XX车型XX车长,运输记录中的运输平均价
对应实体类
public class TransportRecord {
private String startAddressName;
private String endAddressName;
private String carNum;
private int carType;
private float carLength;
private Date createTime;
private float price;
/**
* 分组字段: startAddressName||endAddressName||carType||carLength
* eg: xx市||xx市||1||1.9
**/
private String groupByStr;
// getter..setter 方法省略
}
思路:
1. 将所有运输记录进行 XX市到XX市XX车型XX车长 的分组
2. 分别对分组集合进行相关的计算
分组操作
// 获取所有运输记录
List<TransportRecord> transportRecords = getTransportRecords();
// 分组 利用先前的分组字段,调用 Collectors.groupingBy
Map<String,List<TransportRecord>>map = transportRecords.stream().collect(Collectors.groupingBy(TransportRecord::getGroupByStr));
需求1
找出 XX市到XX市XX车型XX车长运输记录中,出现最多次的运价。如果有多个价格,并且出现的次数相同,则运价取0
// 出现次数最多的价格。 这里对价格出现的次数进行去重,如果去重后的集合元素格式大于 1 则存在出现次数最多的价格
// 出现次数最多的价格定义: 某价格出现的次数大于0的同时要大于其他价格出现的次数
Map<Float,Long> priceCountMap = records.stream()
.collect(Collectors.groupingBy(TransportRecord::getPrice,Collectors.counting()));
Set<Long> princeCountSet = new HashSet<>(priceCountMap.values());
if (princeCountSet.size() > 1) {
long priceMaxCount = princeCountSet.stream().max(Long::compareTo).orElse(0L);
Float price = priceCountMap.entrySet().stream()
.filter(entry -> entry.getValue() == priceMaxCount)
.map(Map.Entry::getKey)
.findFirst()
.orElse(0f);
system.out.println("出现最多的价格是: " + price);
}
需求2
找出XX市到XX市XX车型XX车长,运输记录中的最高价 并且获取出最高价与产生的时间
records.stream()
.max(Comparator.comparing(TransportRecord::getPrice))
.ifPresent(record -> {
system.out.println("最高价是: " + record.getPrice());
system.out.println("最高价产生日期是: " record.getCreateTime());
});
需求3
找出XX市到XX市XX车型XX车长,运输记录中的最低价 并且获取出最低价与产生该价格的时间
records.stream()
.min(Comparator.comparing(TransportRecord::getPrice))
.ifPresent(record -> {
system.out.println("最低价是: " + record.getPrice());
system.out.println("最低价产生日期是: " record.getCreateTime());
});
需求4
求出XX市到XX市XX车型XX车长,运输记录中的运输平均价
double avg = records.stream().mapToDouble(DriverTransportHistoryEntity::getPrice).average().orElse(0.00d);
system.out.println("平均价是: " + avg);
关于max、min的操作与sored这里引用一些说明
min 和 max 的功能也可以通过对 Stream 元素先排序,再 findFirst 来实现,但前者的性能会更好,为 O(n),而 sorted 的成本是 O(n log n)。同时它们作为特殊的 reduce 方法被独立出来也是因为求最大最小值是很常见的操作
附上参考资料链接
IBM学习社区里 关于Java 8 中的 Streams API 详解