0

In a case like this:

public class Order { List<Double> prices = List.of(1.00, 10.00, 100.00); List<Double> pricesWithTax = List.of(1.22, 12.20, 120.00); Double sumBy(/* method reference */) { Double sum = 0.0; for (Double price : /* method reference */) { sum += price; } return sum; } public List<Double> getPrices() { return prices; } public List<Double> getPricesWithTax() { return pricesWithTax; } } 

how can I declare the sumBy method in a way that can be called like this:

Order order = new Order(); var sum = order.sumBy(order::getPrices); var sumWithTaxes = order.sumBy(order::getPricesWithTax); 

I'm not using the Java 8 API for the sum because my goal is only to understand how pass a method reference.

4 Answers 4

3

You seem to want a Supplier like

Double sumBy(Supplier<List<Double>> f) { Double sum = 0.0; for (Double price : f.get()) { sum += price; } return sum; } 

Your List.of syntax was giving me errors. So I did

List<Double> prices = Arrays.asList(1.00, 10.00, 100.00); List<Double> pricesWithTax = Arrays.asList(1.22, 12.20, 120.00); 

Then I tested like

public static void main(String[] args) throws IOException { Order order = new Order(); double sum = order.sumBy(order::getPrices); double sumWithTaxes = order.sumBy(order::getPricesWithTax); System.out.printf("%.2f %.2f%n", sum, sumWithTaxes); } 

Outputs

111.00 133.42 
Sign up to request clarification or add additional context in comments.

4 Comments

List.of() is Java 9+. Come on, join the new world, where the current version is Java 15. 😉
@Andreas Hadoop stack I'm using is stuck at 8 (for now).
FYI: My Eclipse workspace currently has 8 projects with stub main method for writing test code for StackOverflow, one project per Java version from Java 7 to Java 14. Haven't installed Java 15 yet, shame on me. Projects are named Test07 to Test14, with class named the same, which makes it simple to test newer features, or to limit to only older features, as needed. Naming the class the same prevents confusion if more than one of them are open at the same time, which is useful for comparing features/results by Java version.
You should declare sum as double instead of Double. In other words, instead of unboxing the current value and boxing the next value in every loop iteration, only box the end result.
3

Your 2 methods take no argument and return an object, so that fits the Supplier.get() method.

Don't use Double for the sum variable, since that will auto-box and auto-unbox way too much.

Method can be static since it doesn't use any fields or other methods of the class.

static double sumBy(Supplier<List<Double>> listGetter) { double sum = 0.0; for (double price : listGetter.get()) { sum += price; } return sum; } 

Better yet:

static double sumBy(Supplier<List<Double>> listGetter) { return listGetter.get().stream().mapToDouble(Double::doubleValue).sum(); } 

Comments

0

I think the Supplier<T> functional interface is what you’re looking for:

Double sumBy(Supplier<Collection<Double>> supplier) { Collection<Double> prices = supplier.get(); } 

Comments

0

Use Double sumBy(Supplier<List<Double>> doubles)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.