Reputation: 15
I am trying to make a list where I would add items in to my shopping cart, then at check out it would show how many occurrences of items there are by using a HashMap.
public class ShoppingCart
{
private ArrayList<Items> ShoppingCart;
public ShoppingCart()
{
ShoppingCart = new ArrayList<Items>();
}
public void addItems(Items newItems)
{
ShoppingCart.add(newItems);
}
public ArrayList<Items> getShoppingCart()
{
return ShoppingCart;
}
public void CheckOut()
{
for(int i = 0; i < ShoppingCart.size(); i++)
{
HashMap<String, Integer> itemsMap = new HashMap<String, Integer>();
int a = 1;
if (itemsMap.containsKey(ShoppingCart.get(i).getName()))
{
itemsMap.replace(ShoppingCart.get(i).getName(), a, a++);
}
else
{
itemsMap.put(ShoppingCart.get(i).getName(), a);
}
System.out.println(a +"x "+ShoppingCart.get(i));
}
}
and my items are created with
public class Items
{
private String name;
public Items (String name)
{
this.name = name;
}
public String toString()
{
return name;
}
public String getName()
{
return name;
}
}
In the Main, I would create Items, and Add them to the shopping cart, then ShoppingCart.CheckOut(); my items.
However, if I add 4 "White Bread" like so,
Items bread = new Items("White Bread");
ShoppingCart ShoppingCart = new ShoppingCart();
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
I get
1x White Bread
1x White Bread
1x White Bread
1x White Bread
instead of
4x White Bread
What am I doing wrong?
Upvotes: 1
Views: 99
Reputation: 1155
I believe your problem is that you are creating a new hashmap for every item in your shopping list, try this instead:
public void CheckOut()
{
HashMap<String, Integer> itemsMap = new HashMap<String, Integer>();
for(int i = 0; i < ShoppingCart.size(); i++)
{
if (itemsMap.containsKey(ShoppingCart.get(i).getName()))
{
itemsMap.put(ShoppingCart.get(i).getName(), itemsMap.get(ShoppingCart.get(i).getName())+1);
}
else
{
itemsMap.put(ShoppingCart.get(i).getName(), 1);
}
}
Iterator it = itemsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getValue()+"x " + pair.getKey() );
}
}
Upvotes: 0
Reputation: 9625
2 main problems: - HashMap is created on each iteration, so you loose whatever you had in the map before. - Your system out statement in within the FOR, so you'll get as many lines printed as elements you have in the loop.
Why not use A map to store the items like this?
public class ShoppingCart {
Map<Items, Integer> shoppingCart = new HashMap<>();
public ShoppingCart() {
}
public void addItems(Items newItem) {
int count = shoppingCart.containsKey(newItem) ? shoppingCart.get(newItem) : 0;
shoppingCart.put(newItem, ++count);
}
public List<Items> getShoppingCart() {
return shoppingCart.keySet()
.stream()
.flatMap(item -> Collections.nCopies(shoppingCart.get(item), item).stream())
.collect(Collectors.toList());
}
public void CheckOut() {
for (Map.Entry<Items, Integer> entry : shoppingCart.entrySet()) {
System.out.println(String.format("%dx %s", entry.getValue(), entry.getKey().getName()));
}
}
public static class Items
{
private String name;
public Items (String name)
{
this.name = name;
}
public String toString()
{
return name;
}
public String getName()
{
return name;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Items) {
return name.equals(((Items)obj).getName());
}
return false;
}
}
public static void main(String[] args) {
Items bread = new Items("White Bread");
ShoppingCart ShoppingCart = new ShoppingCart();
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
ShoppingCart.addItems(bread);
ShoppingCart.CheckOut();
System.out.println(ShoppingCart.getShoppingCart());
}
}
Upvotes: 0
Reputation: 18825
Count them in advance and print the sum:
Map<String, Integer> itemsMap = new LinkedHashMap<String, Integer>();
for(int i = 0; i < ShoppingCart.size(); i++)
{
itemsMap.merge(ShoppingCart.get(i).getName(), 1, (old, set) -> old+set);
}
for (Map.Entry <String, Integer> e: itemsMap.entrySet ()) {
System.out.println(e.getValue ()+"x "+e.getKey ());
}
Upvotes: 0
Reputation: 393771
Change
itemsMap.replace(ShoppingCart.get(i).getName(), a, a++);
to
a = itemsMap.get(ShoppingCart.get(i).getName()); // in order to increment the
// current counter value
itemsMap.replace(ShoppingCart.get(i).getName(), a, ++a);
Using post decrement (a++
) doesn't modify the value in the Map, since a++
returns the original value of a
.
In addition, the HashMap
should be initialized outside the loop. Otherwise it will always contain just one element.
Upvotes: 5