Reputation: 115
import java.util.*;
public class Orders {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<String, Map<Double, Double>> myMap = new LinkedHashMap<String, Map<Double, Double>>();
String input = "";
while (true) {
input = scanner.nextLine();
String[] tokens = input.split(" ");
String name = tokens[0];
if ("buy".equals(name)) {
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
Map<Double, Double> innerMap = myMap.get(name);
myMap.put(name, innerMap = new HashMap<>());
innerMap.put(price, quantity);
Double existingQuantity = innerMap.get(price);
if (myMap.containsKey(name)) {
innerMap.replace(innerMap.get(price), price);
myMap.get(name).put(price, existingQuantity + quantity);
}
}
System.out.println(myMap);
}
}
Hello,
What I'm trying to do here is sum the value(quantity) of innerMap for each time a repeating key(name) from the outer map is inputted. I did a lot of research but didn't manage to find a case similar to mine.
For example, an input of
Water 1.20 500
Water 1.20 300
buy
Should yield
Water 1.20 800
Also sorry for my english.
Upvotes: 3
Views: 321
Reputation: 394146
It appears the you have to replace
innerMap.put(price, quantity);
with
innerMap.merge(price, quantity, (q1,q2)->q1+q2);
This way all the quantities that correspond with the same name and the same price will be summed.
It also appears that you should change
Map<Double, Double> innerMap = myMap.get(name);
myMap.put(name, innerMap = new HashMap<>());
to
Map<Double, Double> innerMap = myMap.get(name);
if (innerMap == null) {
myMap.put(name, innerMap = new HashMap<>());
}
since you don't want to overwrite the inner Map
of a given name each time you encounter that name.
To summarize:
while (true) {
input = scanner.nextLine();
String[] tokens = input.split(" ");
String name = tokens[0];
if ("buy".equals(name)) {
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
Map<Double, Double> innerMap = myMap.get(name);
if (innerMap == null) {
myMap.put(name, innerMap = new HashMap<>());
}
innerMap.merge(price, quantity, (q1,q2)->q1+q2);
}
And I believe this can be further simplified as follows:
while (true) {
input = scanner.nextLine();
String[] tokens = input.split(" ");
String name = tokens[0];
if ("buy".equals(name)) {
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
myMap.computeIfAbsent(name,n -> new HashMap<>())
.merge(price, quantity, (q1,q2)->q1+q2);
}
EDIT: For your request in the comment you'll have to keep replacing the key of the inner Maps:
while (true) {
input = scanner.nextLine();
String[] tokens = input.split(" ");
String name = tokens[0];
if ("buy".equals(name)) {
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
Map<Double, Double> innerMap = myMap.computeIfAbsent(name,n -> new HashMap<>());
if (innerMap.isEmpty()) {
innerMap.put(price,quantity);
} else {
innerMap.put(price,quantity + innerMap.remove(innerMap.keySet().iterator().next()));
}
}
Upvotes: 1
Reputation: 438
This will work
import java.util.*;
public class App {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<String, Map<Double, Double>> myMap = new LinkedHashMap<String, Map<Double, Double>>();
String input = "";
while (true) {
input = scanner.nextLine();
String[] tokens = input.split(" ");
String name = tokens[0];
if ("buy".equals(name)) {
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
if(!myMap.containsKey(name)){
myMap.put(name,new HashMap<>());
}
if(myMap.get(name).containsKey(price)){
double previousQuantity = myMap.get(name).get(price);
myMap.get(name).put(price,previousQuantity+quantity);
}
else {
myMap.get(name).put(price,quantity);
}
}
System.out.println(myMap);
}
}
Upvotes: 1
Reputation: 151
Hope. This helps
if ("buy".equals(name))
{
break;
}
double price = Double.parseDouble(tokens[1]);
double quantity = Double.parseDouble(tokens[2]);
Map<Double, Double> innerMap = myMap.getOrDefault(name, new HashMap<>());
Double existingQuantity = innerMap.getOrDefault(price, 0.0);
innerMap.put(price, existingQuantity + quantity);
myMap.put(name, innerMap);
Upvotes: 1