我有两个对应的列表:
public class BookOverallData {
private Long idOfBook;
private String title;
private String authour;
private BigDecimal basePrice;
private Integer discountRate;
}
public class TimeDiscount {
private Long idOfBook;
private Integer discountRate;
}
Set<BookOverallData> booksToReturn
Set<TimeDiscount> actualPromotions
目标是汇总折扣,这意味着将discountRate
中的actualPromotions
与discountRate
列表中的booksToReturn
值相加。两个列表中的对象都可以用idOfBook
进行匹配。
这就是我解决的方法
booksToReturn.forEach(
p -> {
final Optional<TimeDiscount> promotion = actualPromotions.stream().filter(ap -> Objects.equals(ap.getIdOfBook(), p.getIdOfBook())).findFirst();
promotion.ifPresent(ap -> p.setDiscountRate(ap.getDiscountRate() + p.getDiscountRate()));
}
);
我只是在探索流,我认为我的解决方案很笨拙。您将如何使用流和功能方法以更优雅的方式解决此问题?
答案 0 :(得分:3)
我首先创建一个从log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.File=c:/MyLoggingDir/application6.log
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
log4j.appender.rollingFile.MaxFileSize=10MB
log4j.appender.rollingFile.MaxBackupIndex=5
log4j.appender.rollingFile.append=true
log4j.rootCategory=ALL, rollingFile
到TimeDiscount::getIdOfBook
的映射:
TimeDiscount
那我要做:
Map<Long, TimeDiscount> accumulator =
actualPromotions.stream()
.collect(toMap(TimeDiscount::getIdOfBook, Function.identity()));
或者如果您出于某些原因想继续使用booksToReturn.forEach(e -> {
TimeDiscount timeDiscount = accumulator.get(e.getIdOfBook());
if (timeDiscount != null) e.setDiscountRate(e.getDiscountRate() + timeDiscount.getDiscountRate());
});
。
Optional
这改善了booksToReturn.forEach(e ->
Optional.ofNullable(accumulator.get(e.getIdOfBook()))
.ifPresent(p -> e.setDiscountRate(e.getDiscountRate() + p.getDiscountRate()))
);
中每个元素在actualPromotions.stream()
中的低效率查找。
答案 1 :(得分:1)
一种实现方法是使用:
booksToReturn.forEach(p -> actualPromotions.stream()
.filter(actualPromotion -> actualPromotion.getIdOfBook().equals(p.getIdOfBook()))
.forEach(actualPromotion -> p.setDiscountRate(p.getDiscountRate() + actualPromotion.getDiscountRate())));
假设actualPromotion.getIdOfBook()
和p.getIdOfBook()
在您的Set
中是唯一的。
答案 2 :(得分:1)
我尚未对此进行测试: 试试这个
Map<Long,Integer> map1 = actualPromotions
.stream()
.collect(Collectors.toMap(TimeDiscount::getIdOfBook,TimeDiscount::getDiscountRate));
然后在以下位置使用此地图:
booksToReturn.stream()
.filter(b->map1.containsKey(b.getIdOfBook()))
.map(p->{p.setDiscountRate(map1.get(p.getIdOfBook()) + p.getDiscountRate());return p;}) // .map(p->setSumDiscountRate(map1.get(p.getIdOfBook()) + p.getDiscountRate()))
.collect(Collectors.toList());
尝试在BookOverallData
类中声明一个新方法。
public BookOverallData setSumDiscountRate(Integer dis){
this.discountRate = dis;
return this;
}