Hi Tom,
The answer given by Jeanne is perfectly correct, and it might be what you are looking for. However, Your code is having design problems. So minimal changes will not really fix it. The major problem is about your model. Your are dealing with invoices. Invoices are made of invoice lines, each line referencing a part and a quantity. So
you should start with creating the right model for your problem.
A
Part may be modeled as:
Note that validation should not be made in the constructor. Constructors should never show exceptions. Also note that the product method could, instead of throwing exceptions, return a special kind of
Optional that might contain the exception, letting the choice to the caller to either throw it or do something else.
Java 8 does not offer such a class, but I describe one in my book,
Functional Programming in Java.
Next you need an
InvoiceLine class to represent each line in an invoice. An
InvoiceLine is constructed with a reference to a part and a quantity. This class will also be responsible for calculating the total price for the line, and for providing the comparators:
Note that you should NEVER use
double to represent prices, since prices are fix decimal value while
double are floating decimals. But this is another story.
Then you need an
Invoice class to represent each invoice:
Now, you may write the
ProcessInvoices program as:
Note that there is no need to write something like:
Doing this could lead the compiler to create unnecessary object. In general, you should not declare explicit object to wrap functions. Lambdas and method references free us from writing anonymous classes, but it also free the compiler (and/or the JVM) to create useless objects.
However, it might sometimes be interesting to create such objects in order to eliminate duplicate code. For example, you could replace:
with:
Not sure if the compiler or the JVM are able to optimize this code by using a method reference for the
map parameter, but even if not, this version is better because it reduces duplication.