Java 选择更有利可图的流结果
目前,我正在努力解决我的小型产品管理应用程序中的折扣计算问题Java 选择更有利可图的流结果,java,java-8,stream,java-stream,Java,Java 8,Stream,Java Stream,目前,我正在努力解决我的小型产品管理应用程序中的折扣计算问题 public class Customer { private String name; private String surname; private LocalDate birthDate; private String email; } public class Order { private Customer customer; private Product product; private I
public class Customer {
private String name;
private String surname;
private LocalDate birthDate;
private String email;
}
public class Order {
private Customer customer;
private Product product;
private Integer quantity;
private LocalDate estimatedRealizationDate;
}
public class Product {
private String name;
private BigDecimal price;
private Category category;
}
与龙目岛公用事业公司
我有一个Orders类,它包含一个订单列表
public class Orders {
private final List<Order> productList;
private static final int MAXIMAL_AGE_WITH_DISCOUNT = 25;
private static final BigDecimal DISCOUNT_RATIO_FOR_CUSTOMER_YOUNGER_THAN_25 = BigDecimal.valueOf(0.97);
private static final BigDecimal DISCOUNT_RATIO_FOR_ESTIMATED_DELIVERY_DATE_SMALLER_THAN_2 = BigDecimal.valueOf(0.98);
private static final int MAXIMAL_DATES_NUMBER_FOR_DISCOUNT = 2;
}
我想给每个25岁以下的客户3%的折扣,如果订单预计交货日期从现在起少于2天,我想给客户2%的折扣,但我想给客户选择一个更有利可图的折扣
我写了我的代码片段,但就我所见,我的版本在某些情况下会结合折扣,这是不可取的
BigDecimal totalPriceOfAllOrdersAfterPriceReduction() {
return productList.stream().map(i -> {
if (between(i.getCustomer().getBirthDate(), LocalDate.now()).getYears() < MAXIMAL_AGE_WITH_DISCOUNT) {
return i.getProduct().getPrice().multiply(DISCOUNT_RATIO_FOR_CUSTOMER_YOUNGER_THAN_25).multiply(BigDecimal.valueOf(i.getQuantity()));
}
if (between(i.getEstimatedRealizationDate(), LocalDate.now()).getDays() < MAXIMAL_DATES_NUMBER_FOR_DISCOUNT) {
return i.getProduct().getPrice().multiply(DISCOUNT_RATIO_FOR_ESTIMATED_DELIVERY_DATE_SMALLER_THAN_2).multiply(BigDecimal.valueOf(i.getQuantity()));
}
return i.getProduct().getPrice();
}).reduce(BigDecimal.ZERO, BigDecimal::add);
}
BigDecimalTotalPriceOfAllordersAfterPriceReduction(){
返回productList.stream().map(i->{
如果(介于(i.getCustomer().getBirthDate()、LocalDate.now()).getYears()<带折扣的最大年龄){
返回i.getProduct().getPrice().multiply(小于25岁的客户的折扣率)。multiply(BigDecimal.valueOf(i.getQuantity());
}
如果(介于(i.getEstimatedRealizationDate()、LocalDate.now()).getDays()<折扣的最大日期数){
返回i.getProduct().getPrice().multiply(折扣率,用于估计的交货日期小于2)。multiply(BigDecimal.valueOf(i.getQuantity());
}
返回i.getProduct().getPrice();
}).reduce(BigDecimal.ZERO,BigDecimal::add);
}
在完成整个操作后,我要汇总所有订单的总价(数量*价格)
我希望通过Java流的使用实现这一点
提前感谢您的帮助。请将第二个if放在第一个if的else部分
BigDecimal totalPriceOfAllOrdersAfterPriceReduction() {
return productList.stream().map(i -> {
if (between(i.getCustomer().getBirthDate(), LocalDate.now()).getYears() < MAXIMAL_AGE_WITH_DISCOUNT) {
return i.getProduct().getPrice().multiply(DISCOUNT_RATIO_FOR_CUSTOMER_YOUNGER_THAN_25).multiply(BigDecimal.valueOf(i.getQuantity()));
} else{
if (between(i.getEstimatedRealizationDate(), LocalDate.now()).getDays() < MAXIMAL_DATES_NUMBER_FOR_DISCOUNT) {
return i.getProduct().getPrice().multiply(DISCOUNT_RATIO_FOR_ESTIMATED_DELIVERY_DATE_SMALLER_THAN_2).multiply(BigDecimal.valueOf(i.getQuantity()));
}
}
return i.getProduct().getPrice();
}).reduce(BigDecimal.ZERO, BigDecimal::add);
}
BigDecimalTotalPriceOfAllordersAfterPriceReduction(){
返回productList.stream().map(i->{
如果(介于(i.getCustomer().getBirthDate()、LocalDate.now()).getYears()<带折扣的最大年龄){
返回i.getProduct().getPrice().multiply(小于25岁的客户的折扣率)。multiply(BigDecimal.valueOf(i.getQuantity());
}否则{
如果(介于(i.getEstimatedRealizationDate()、LocalDate.now()).getDays()<折扣的最大日期数){
返回i.getProduct().getPrice().multiply(折扣率,用于估计的交货日期小于2)。multiply(BigDecimal.valueOf(i.getQuantity());
}
}
返回i.getProduct().getPrice();
}).reduce(BigDecimal.ZERO,BigDecimal::add);
}
另一个使其更具可读性和可跟踪性的方法是在订单上添加一个“折扣”字段,然后
@Builder
@Getter
@ToString
public static class Order {
private Customer customer;
private Product product;
private Integer quantity;
private LocalDate estimatedRealizationDate;
private BigDecimal discount = BigDecimal.ZERO;
public boolean threePercent(){
return Period.between(this.getCustomer().birthDate, LocalDate.now()).getYears() < MAXIMAL_AGE_WITH_DISCOUNT;
}
public boolean twoPercent(){
return Period.between(this.estimatedRealizationDate, LocalDate.now()).getYears() < MAXIMAL_DATES_NUMBER_FOR_DISCOUNT;
}
}
public static Order update(Order o){
if(o.threePercent()){
o.discount = DISCOUNT_RATIO_FOR_CUSTOMER_YOUNGER_THAN_25;
}else{
if(o.twoPercent()){
o.discount = DISCOUNT_RATIO_FOR_ESTIMATED_DELIVERY_DATE_SMALLER_THAN_2;
}
}
return o;
}
public static BigDecimal totalPriceOfAllOrdersAfterPriceReduction(List<Order> orders){
return orders
.stream()
.map(Scratch::update)
.peek(System.out::println)
.map(o -> o.product.price.multiply(o.discount).multiply(BigDecimal.valueOf(o.quantity)))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
@Builder
@吸气剂
@托斯特林
公共静态类秩序{
私人客户;
私人产品;
私有整数数量;
私有LocalDate estimatedRealizationDate;
私有BigDecimal折扣=BigDecimal.0;
公共布尔值百分之三(){
返回期.between(this.getCustomer().birthDate,LocalDate.now()).getYears()<最大年龄折扣;
}
公共布尔值百分之二(){
返回期.between(this.estimatedRealizationDate,LocalDate.now()).getYears()o.product.price.multiply(o.discount).multiply(BigDecimal.valueOf(o.quantity)))
.reduce(BigDecimal.ZERO,BigDecimal::add);
}
附带问题:为什么要使用BigDecimal
?最小货币的int
就足够了吗?类似于intpriceincents=100
其中100
cents等于1
dollar?在处理货币时,使用BigDecimal类是常见的,并且被认为是安全的,因此我在本例中使用它。顺便说一句,您的解决方案相当可观,在问题解决后,我肯定会深入研究。我想是精度的损失导致了int
“不安全”,您当然可以使用双倍的值进行计算,但然后再次返回int
。这样,您可以在整个计算过程中保持精度,然后再次使用int
s
@Builder
@Getter
@ToString
public static class Order {
private Customer customer;
private Product product;
private Integer quantity;
private LocalDate estimatedRealizationDate;
private BigDecimal discount = BigDecimal.ZERO;
public boolean threePercent(){
return Period.between(this.getCustomer().birthDate, LocalDate.now()).getYears() < MAXIMAL_AGE_WITH_DISCOUNT;
}
public boolean twoPercent(){
return Period.between(this.estimatedRealizationDate, LocalDate.now()).getYears() < MAXIMAL_DATES_NUMBER_FOR_DISCOUNT;
}
}
public static Order update(Order o){
if(o.threePercent()){
o.discount = DISCOUNT_RATIO_FOR_CUSTOMER_YOUNGER_THAN_25;
}else{
if(o.twoPercent()){
o.discount = DISCOUNT_RATIO_FOR_ESTIMATED_DELIVERY_DATE_SMALLER_THAN_2;
}
}
return o;
}
public static BigDecimal totalPriceOfAllOrdersAfterPriceReduction(List<Order> orders){
return orders
.stream()
.map(Scratch::update)
.peek(System.out::println)
.map(o -> o.product.price.multiply(o.discount).multiply(BigDecimal.valueOf(o.quantity)))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}