A question from a total newbie. Sorry.
I have this customersOrders
HashMap
that takes String
as keys and ArrayList<Double>
as values. I need to find the total sum of orders for each customer and the maximum total sum in order to find the biggest customer. How do I manage to do that using just nested For
loops and HashMap
methods? I'm totally stuck on that.
public class Test {
public static void main(String[] args) {
HashMap<String, ArrayList<Double>> customersOrders;
customersOrders = new HashMap<>();
ArrayList<Double> orders = new ArrayList<>();
orders.add(55.50);
orders.add(78.30);
orders.add(124.75);
customersOrders.put("John", orders);
orders = new ArrayList<>();
orders.add(28.35);
orders.add(37.40);
customersOrders.put("Helen", orders);
orders = new ArrayList<>();
orders.add(150.10);
customersOrders.put("Thomas", orders);
orders = new ArrayList<>();
orders.add(230.45);
orders.add(347.20);
customersOrders.put("Robert", orders);
orders = new ArrayList<>();
orders.add(530.25);
orders.add(325.40);
orders.add(11550.70);
orders.add(2480.65);
customersOrders.put("Jennifer", orders);
System.out.println(customersOrders);
}
}
So far I've been trying to do something like this but obviously with no success:
double maxOrder = 0;
String customerName = "";
for (ArrayList<Double> orders : customersOrders.values()) {
for (double orderPrice : orders) {
if (orderPrice > maxOrder) {
maxOrder = orderPrice;
}
}
}
for (String name : customersOrders.keySet()) {
if (maxOrder.equals(customersOrders.get(name))) {
customerName = name;
break;
}
}
CodePudding user response:
You could create another HashMap
which keeps your sums and then find the maximum of them.
First iterate through all your HashMap
keys and find the sums for each customer like this:
HashMap<String, ArrayList<Double>> customerOrders = new HashMap<>();
// Fill your HashMap as you've done above
HashMap<String, Double> customerSums = new HashMap<>(); // The new HashMap that keeps the sums
for (String customerName : customerOrders.keySet()) // Foreach customer
{
double currentSum = 0;
for (Double aDouble : customerOrders.get(customerName))
{
currentSum = aDouble; // Sum the orders
}
customerSums.put(customerName, currentSum); // Put the sum in your new HashMap
}
Now finding the maximum should be very straightforward. Try to do that :D
CodePudding user response:
Maybe something like this:
Map<String, Double> customersSum = new HashMap<>();
Double maxSum = Double.MIN_VALUE;
String customerWithMaxSum;
for (Map.Entry<String, List<Double>> entry: customersOrders.entrySet()) {
String customerId = entry.getKey();
List<Double> customerOrders = entry.getValue();
Double customerSum = customerOrders.stream().mapToDouble(d -> d).sum();
customersSum.put(customerId, customerSum);
if (customerSum > maxSum) {
maxSum = customerSum;
customerWithMaxSum = customerId;
}
}
Also could use stream pi for the second part:
Optional<String> customerWithMaxSum = customersSum.entrySet()
.stream()
.max(Comparator.comparingDouble(Map.Entry::getValue))
.map(Map.Entry::getKey);
CodePudding user response:
Your logic code is not correct
for (double orderPrice : orders) {
if (orderPrice > maxOrder) {
maxOrder = orderPrice;
}
}
You are not adding the prices then comparing with maxOrder
you instead compare each price with maxOrder
. this is not what was required in your question.
You should do this instead
double ordersSum = 0;
for (double orderPrice : orders) {
ordersSum = orderPrice;
}
if (ordersSum > maxOrder) {
maxOrder = ordersSum;
}
and in your second for loop, you are comparing a double value with an arraylist which should result a compilation error you should compare the sum for products from each custom to maxOrder
.
I should note here that this code is not very efficient you can instead loop on keys as you did in the second loop then calculate the sum inside of it and compare to maxOrder
I will leave this implementation as an exercise for you.
CodePudding user response:
You are iterating over the values in the orders
Map. This doesn't tell you who that is associated with. Instead, you could iterate over the keyset or entryset, calculate the sum for that customer, and compare this to a running maximum. Since you specified using for-loops, the following excludes use of the Stream API.
String maxOrderCustomer = null;
double maxOrder = 0.0;
for (Map.EntrySet<String,List<Double>> entry : customerOrders.entrySet()) {
Double sum = 0.0;
for (Double order : entry.getValue();
sum = order;
}
if (order > maxOrder) {
maxOrder = order;
maxOrderCustomer = entry.getKey();
}
}
At this point, you will have the name of the customer with the largest sum and that sum value. If you want to display the relevant list of orders, you can use the name to pull the list from the original Map.