如何在这种情况下使用Java 8的Stream API?

huangapple go评论84阅读模式
英文:

how to use Java 8 streamAPI in this situtation

问题

public int getTotalPrice(ArrayList<Book> books) {
    int sum = books.stream()
            .mapToInt(Book::getPrice)
            .sum();
    if (books.size() >= 5 && sum >= this.minimumPrice) {
        int res = (int) books.stream()
                .mapToInt(Book::getPrice)
                .boxed()
                .sorted(Collections.reverseOrder())
                .limit(2)
                .mapToDouble(price -> price * 0.5)
                .sum();
        return books.stream()
                .skip(2)
                .mapToInt(Book::getPrice)
                .sum()
                + res;
    }
    return sum;
}

根据你提供的代码,你已经使用了流API来实现你的要求。排序是必要的,因为你需要找到最贵的两本书并对它们进行折扣,然后计算剩余书的价格总和。你的代码已经正确地完成了这个任务。如果你有其他问题或需要进一步的帮助,请随时提问。

英文:
public int getTotalPrice(ArrayList&lt;Book&gt; books) {
        int sum = books.stream()
                .mapToInt(Book::getPrice)
                .sum();
        if (books.size() &gt;= 5 &amp;&amp; sum &gt;= this.minimumPrice) {
            int res =(int) books.stream()
                    .mapToInt(Book::getPrice)
                    .boxed()
                    .sorted(Collections.reverseOrder())
                    .limit(2)
                    .mapToDouble(price -&gt; price * 0.5)
                    .sum();
            return books.stream()
                    .skip(2)
                    .mapToInt(Book::getPrice)
                    .sum()
                    + res;
        }
        return sum;
    }

I want to implement the "getTotalPrice" method.

The discount rules are as follows

If you have 5 or more books and the price of all of them added together is equal to or greater than "this.minimumPrice", then the two most expensive books in your cart will be half price.

I want to implement this with stremapi in java 8. How can I do that?

The above code was written by myself.

If you have a better way to do it, I'd love to hear about it.

I extracted the prices from the stream of books and sorted them in descending order.

I discounted the top two most expensive prices by 50% and substituted them into "res".

Then, to get the sum of the prices of the remaining books, I skipped two and took the sum.

Is sorting necessary here to get the prices of the remaining books?

答案1

得分: 0

你的方法解决问题没有问题。但是我仍然建议你进行改进,不要将所有操作都放在一个方法中,而是将其分解为多个方法,这样每个方法只执行一个任务。这样可以使你的代码更易读和易维护。特别是在需求发生变化时,比如折扣率变化或需要添加额外的折扣活动时。

例如,计算总金额和计算折扣可以移到它们自己的方法中。

public int getTotalPrice(List<Book> books) {
    int totalSum              = getTotalSum(books);
    boolean hasMinBookCount   = books.size() > 4;
    boolean overTotalMinPrice =  totalSum > this.minimumPrice;

    if (!hasMinBookCount || !overTotalMinPrice){
        return totalSum;
    }
    return (int) (totalSum - getDiscount(books));
}

public int getTotalSum(List<Book> books) {
    return books.stream()
                .mapToInt(Book::getPrice)
                .sum();
}

public double getDiscount(List<Book> books) {
    double discountRate = 0.5;
    return discountRate * books.stream()
                               .sorted(Comparator.comparing(Book::getPrice, Comparator.reverseOrder()))
                               .limit(2)
                               .mapToInt(Book::getPrice)
                               .sum();
}

通过上面的改进,一眼就能看出在什么条件下会计算折扣。

还有一些备注:在涉及价格或货币的情况下,最好使用 double 类型,甚至更好的是 BigDecimal,而不是 int。我会留给你来改进这一点。在方法参数中使用 List,而不是具体的实现类,如 ArrayList(编程针对接口)。

英文:

It's perfectly okay to solve it the way you did. But still a suggestion for improvement would be not to make everything in one method but to outsource in several methods, so that one method does only one task. This makes your code more readable and maintainable. Especially when requirements change, like the discount rate or when additional discount campaigns should be added.

For example, the calculation of the total sum and the calculation of discount could be moved to their own methods.

public int getTotalPrice(List&lt;Book&gt; books) {
    int totalSum              = getTotalSum(books);
    boolean hasMinBookCount   = books.size() &gt; 4;
    boolean overTotalMinPrice =  totalSum &gt; this.minimumPrice;

    if (!hasMinBookCount || !overTotalMinPrice){
        return totalSum;
    }
    return (int) (totalSum - getDiscount(books));
}

public int getTotalSum(List&lt;Book&gt; books) {
    return books.stream()
                .mapToInt(Book::getPrice)
                .sum();
}

public double getDiscount(List&lt;Book&gt; books) {
    double discountRate = 0.5;
    return discountRate * books.stream()
                               .sorted(Comparator.comparing(Book::getPrice, Comparator.reverseOrder()))
                               .limit(2)
                               .mapToInt(Book::getPrice)
                               .sum();
}

Wit the above, it is now at first glance clear on which condition a discount is calculated.

A few remarks: It is better when it comes to price or money in general to use the type double or even better BigDecimal instead of int. I'll leave it to you to improve that. Use List as parameter instead of a concrete implementation like ArrayList (Coding to an interface).

huangapple
  • 本文由 发表于 2023年7月13日 15:31:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76676929.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定