In my java program, there are objects of a class called salesperson
.
These objects have an attribute called sales
and an attribute called name
.
I want to compare the sales values to find the largest value and then print out the name of the object that has the highest sale value.
How I did it was
double highSales;
String highSalesString;
highSales=first.getJanSales();
highSalesString=first.getSName() " " first.getTitle();
if (second.getJanSales()>highSales)
{
highSales=second.getJanSales();
highSalesString=second.getSName() " " second.getTitle();
}
if (third.getJanSales()>highSales)
{
highSales=third.getJanSales();
highSalesString=third.getSName() " " third.getTitle();
}
I feel like there's a much simpler way to achieve this.
CodePudding user response:
Comparator
You just got to use a Comparator
or implement Comparable
accordingly.
For example
List<SalesPerson> persons = ...
persons.sort(Comparator.comparingInt(SalesPerson::getSales).reverseOrder());
SalesPerson personWithMostSales = persons.get(0);
System.out.println(personWithMostSales.getName());
If all you want is just this one entry, you do not have to sort the whole list:
SalesPerson personWithMostSales = persons.stream()
.max(Comparator.comparingInt(SalesPerson::getSales).reverseOrder())
.orElseThrow();
System.out.println(personWithMostSales.getName());
There is also Collections.max(...)
which you can use instead of the stream.
Comparable
If you think that sorting SalesPerson
by their sales
is a reasonable thing to do by default (a so called natural order), you can also let them implement Comparable
accordingly:
public class SalesPerson implements Comparable<? super SalesPerson> {
...
@Override
public int compareTo(SalesPerson other) {
return -1 * Integer.compare(sales, other.sales);
}
}
and then you could put them into a sorted collection such as TreeSet
and it would keep them sorted for you already. Note however that such collections usually do not allow that you modify sales
while the persons have already been added to the collection.
CodePudding user response:
I want to compare the sales values to find the largest value and then print out the name of the object that has the highest sale value.
I would skip the sorting since all you want seems to be the name of the person that had maximum sales. Assuming your sales people are in a List you can do it as follows:
The record for demo purposes (behaves like a class).
record SalesPerson(String getName, double getSales) {
@Override
public String toString() {
return "Name: " getName ", " "Sales: $" getSales;
}
}
Create some data
List<SalesPerson> sales = List.of(new SalesPerson("John", 492.44 ),
new SalesPerson("Mary", 688.68), new SalesPerson("Bob", 533.22));
- this streams the SalesPerson instances
- then using a comparator, finds the maximum based on the sales value.
max
returns anOptional<SalesPerson>
.
Optional<SalesPerson> bestSalesPerson = sales.stream()
.max(Comparator.comparingDouble(SalesPerson::getSales));
if (bestSalesPerson.isPresent()) {
System.out.println(bestSalesPerson.get());
}
Prints
Name: Mary, Sales: $688.68
If you don't wish to use a stream you can do it with a loop.
- if the list is not empty assign the first person to
best
- then iterate over the list, comparing each candidate's record to the current best and adjust as required. Extra checks are added in case the list is empty. These can be eliminated if not necessary.
SalesPerson best = null;
if (!sales.isEmpty()) {
best = sales.get(0);
}
for (int i = 1; i < sales.size(); i ) {
SalesPerson candidate = sales.get(i);
if (candidate.getSales > best.getSales) {
best = candidate;
}
}
if (best != null) {
System.out.println(best);
}