java8中的Stream API实战
目录
根据以下两个list集合来演示Stream API
List<PayRecordBO> list1 = new ArrayList<>();
PayRecordBO payRecordBO1 = new PayRecordBO();
payRecordBO1.setChannelNo("1");
payRecordBO1.setAmount(new BigDecimal("0.11"));
payRecordBO1.setResponseCode("success");
list1.add(payRecordBO1);
PayRecordBO payRecordBO2 = new PayRecordBO();
payRecordBO2.setChannelNo("2");
payRecordBO2.setAmount(new BigDecimal("0.05"));
payRecordBO2.setResponseCode("success");
list1.add(payRecordBO2);
PayRecordBO payRecordBO3 = new PayRecordBO();
payRecordBO3.setChannelNo("3");
payRecordBO3.setAmount(new BigDecimal("0.81"));
payRecordBO3.setResponseCode("success");
list1.add(payRecordBO3);
PayRecordBO payRecordBO35 = new PayRecordBO();
payRecordBO35.setChannelNo("5");
payRecordBO35.setAmount(new BigDecimal("0.31"));
payRecordBO35.setResponseCode("success");
list1.add(payRecordBO35);
PayRecordBO payRecordBO66 = new PayRecordBO();
payRecordBO66.setChannelNo("8");
payRecordBO66.setAmount(new BigDecimal("0.31"));
payRecordBO66.setResponseCode("fail");
list1.add(payRecordBO66);
PayRecordBO payRecordBO9 = new PayRecordBO();
payRecordBO9.setChannelNo("9");
payRecordBO9.setAmount(new BigDecimal("0.92"));
//payRecordBO9.setResponseCode("fail");
list1.add(payRecordBO9);
PayRecordBO payRecordBO10 = new PayRecordBO();
payRecordBO10.setChannelNo("10");
payRecordBO10.setAmount(new BigDecimal("1.92"));
payRecordBO10.setResponseCode("fail");
list1.add(payRecordBO10);
// ==========================
List<PayRecordBO> list2 = new ArrayList<>();
PayRecordBO payRecordBO4 = new PayRecordBO();
payRecordBO4.setChannelNo("4");
payRecordBO4.setAmount(new BigDecimal("0.31"));
list2.add(payRecordBO4);
PayRecordBO payRecordBO5 = new PayRecordBO();
payRecordBO5.setChannelNo("3");
payRecordBO5.setAmount(new BigDecimal("0.31"));
list2.add(payRecordBO5);
PayRecordBO payRecordBO6 = new PayRecordBO();
payRecordBO6.setChannelNo("2");
payRecordBO6.setAmount(new BigDecimal("0.22"));
list2.add(payRecordBO6);
PayRecordBO payRecordBO8 = new PayRecordBO();
payRecordBO8.setChannelNo("8");
payRecordBO8.setAmount(new BigDecimal("0.31"));
list2.add(payRecordBO8);
PayRecordBO payRecordBO99 = new PayRecordBO();
payRecordBO99.setChannelNo("9");
payRecordBO99.setAmount(new BigDecimal("0.19"));
list2.add(payRecordBO99);
PayRecordBO payRecordBO12 = new PayRecordBO();
payRecordBO12.setChannelNo("10");
payRecordBO12.setAmount(new BigDecimal("5.92"));
list2.add(payRecordBO12);
1、以list1为基准,两个list集合中根据某个字段求交集
List<PayRecordBO> eqList = list1.parallelStream().filter(x ->
list2.parallelStream().map(PayRecordBO::getChannelNo).collect(Collectors.toList()).contains(x.getChannelNo())
).collect(Collectors.toList());
log.info("相同数据:{}",eqList);
2、以list1为基准,两个list集合中根据某个字段求差集
List<PayRecordBO> collect = list1.parallelStream().filter(x -> !eqList.contains(x)).collect(Collectors.toList());
log.info("差集数据:{}",collect);
3、以list1为基准,两个list集合中根据某个字段求交集
List<PayRecordBO> eqList = list1.parallelStream().filter(x ->
list2.parallelStream().anyMatch(r -> r.getChannelNo().equalsIgnoreCase(x.getChannelNo()))
).collect(Collectors.toList());
log.info("相同数据:{}", eqList);
4、以list1为基准,两个list集合中根据某个字段求差集
List<PayRecordBO> poolList = list1.parallelStream().filter(x ->
list2.parallelStream().noneMatch(r -> r.getChannelNo().equalsIgnoreCase(x.getChannelNo()))
).collect(Collectors.toList());
log.info("差集数据:{}", poolList);
5、以list1为基准,两个list集合中根据某两个字段求交集
List<PayRecordBO> intersectList = list1.stream()
.filter(pe -> findOver(pe.getChannelNo(), pe.getAmount(), list2) > -1).collect(Collectors.toList());
log.info("平台长款:{}", intersectList);
6、以list1为基准,两个list集合中根据某两个字段求交集
List<PayRecordBO> shortList = list1.stream()
.filter(pe -> findShort(pe.getChannelNo(), pe.getAmount(), list2) > -1).collect(Collectors.toList());
log.info("平台短款:{}", shortList);
7、以list2为基准,两个list集合求交集、差集
List<PayRecordBO> poolBankList = list2.parallelStream().filter(x ->
list1.parallelStream().noneMatch(r -> r.getChannelNo().equalsIgnoreCase(x.getChannelNo()))
).collect(Collectors.toList());
log.info("bank缓存池数据:{}", poolBankList);
List<PayRecordBO> bankFailList = list2.stream()
.filter(pe -> findFail(pe.getChannelNo(), pe.getAmount(), list1) > -1).collect(Collectors.toList());
log.info("bank状态不符数据,金额相同:{}", bankFailList);
List<PayRecordBO> bankFailOverList = list2.stream()
.filter(pe -> findFailOver(pe.getChannelNo(), pe.getAmount(), list1) > -1).collect(Collectors.toList());
log.info("bank平台长款数据,状态不符:{}", bankFailOverList);
List<PayRecordBO> bankFailShortList = list2.stream()
.filter(pe -> findFailShort(pe.getChannelNo(), pe.getAmount(), list1) > -1).collect(Collectors.toList());
log.info("bank平台短款数据,状态不符:{}", bankFailShortList);
8、求总金额
List<PayRecordBO> recRecord = list1.stream().filter(x -> RecConstant.IN.equalsIgnoreCase(x.getTransType())).collect(Collectors.toList());
List<PayRecordBO> recRefundRecord = list1.stream().filter(x -> RecConstant.OUT.equalsIgnoreCase(x.getTransType())).collect(Collectors.toList());
recRecord.stream().filter(x -> x.getAmount() != null).map(PayRecordBO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
recRefundRecord.stream().filter(x -> x.getAmount() != null).map(PayRecordBO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
9、CollectUtil工具类
public final class CollectUtil {
public static int findFailShort(String playerId, BigDecimal amt, List<PayRecordBO> list) {
int res = -1;
for (int i = 0; i < list.size(); i++) {
boolean flag = list.get(i).getChannelNo().equals(playerId)
&& (StringUtils.isBlank(list.get(i).getResponseCode())
|| !RecConstant.SUCCESS.equals(list.get(i).getResponseCode()))
&& amt.compareTo(list.get(i).getAmount()) > 0;
if (flag) {
res = i;
break;
}
}
return res;
}
public static int findFailOver(String playerId, BigDecimal amt, List<PayRecordBO> list) {
int res = -1;
for (int i = 0; i < list.size(); i++) {
boolean flag = list.get(i).getChannelNo().equals(playerId)
&& (StringUtils.isBlank(list.get(i).getResponseCode())
|| !RecConstant.SUCCESS.equals(list.get(i).getResponseCode()))
&& amt.compareTo(list.get(i).getAmount()) < 0;
if (flag) {
res = i;
break;
}
}
return res;
}
public static int findFail(String playerId, BigDecimal amt, List<PayRecordBO> list) {
int res = -1;
for (int i = 0; i < list.size(); i++) {
boolean flag = list.get(i).getChannelNo().equals(playerId)
&& (StringUtils.isBlank(list.get(i).getResponseCode())
|| !RecConstant.SUCCESS.equals(list.get(i).getResponseCode()))
&& amt.compareTo(list.get(i).getAmount()) == 0;
if (flag) {
res = i;
break;
}
}
return res;
}
public static int findShort(String playerId, BigDecimal amt, List<PayRecordBO> list) {
int res = -1;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getChannelNo().equals(playerId) && amt.compareTo(list.get(i).getAmount()) < 0) {
res = i;
break;
}
}
return res;
}
public static int findOver(String playerId, BigDecimal amt, List<PayRecordBO> list) {
int res = -1;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getChannelNo().equals(playerId) && amt.compareTo(list.get(i).getAmount()) > 0) {
res = i;
break;
}
}
return res;
}
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}