I am trying to implement a method to view a list of items and their quantities, without being repeated. I am doing this using ArrayList which will hold objects of the type Item which I created. The Problem is in the loop where I remove duplicates from the a copy of the original list as it doesn't show the last two Items in the list and I don't know how to fix it. Here is the code. Item is very simple object, it contains (int identifier, int price, String name)
private ArrayList list;
public void print(ListOfItems storeList)
{
list = storeList.getList();
if ( list.size() == 0)
System.out.println("Sorry! There are no available Items at the store at this moment.");
/** I changed this section
else
{
Object[] originalItems = list.toArray();
ArrayList copy = storeList.getCopy(storeList.getList());
Object[] copyItems = copy.toArray();
System.out.println("Here is a list Of available items in this Store");
System.out.println("Name\tIdentifier\tprice\tQuantity");
//this loop is wrong
for (int i = 0; i < originalItems.length-1; i++)
{
for (int j = i+1; j < originalItems.length; j++)
{
if (originalItems[i].equals(originalItems[j]) && copyItems[j] != null)
{
copy.remove(originalItems[j]);
}
}
}
**/
//Below is the write loop
else
{
Object[] originalItems = list.toArray();
ArrayList copy = new ArrayList(list.size());
for (int i = 0; i < originalItems.length; i++)
{
Item item = (Item) originalItems[i];
if (copy.contains(item) == false)
{
copy.add(item);
}
}
Object[]cop = copy.toArray();
for (int i = 0; i < cop.length; i++)
{
if (cop[i] != null)
{
Item item = (Item) copyItems[i];
System.out.print(item.getName() + "\t");
System.out.print(item.getIdentifier() + "\t\t");
System.out.print(item.getPrice() + "\t");
System.out.print(Methods.getOccurences(list, item));
System.out.println();
}
}
System.out.print("*****************************");
}
}
Here is the class for ListOfItems
import java.util.ArrayList;
public class ListOfItems
{
int numOfItemsInStore = 50;
private ArrayList list = new ArrayList(numOfItemsInStore);
public ListOfItems()
{
Item item1 = new Item (111, 50, "Item1");
list.add(item1);
Item item2 = new Item (222, 99, "Item2");
list.add(item2);
Item item3 = new Item (333, 20, "Item3");
list.add(item3);
Item item4 = new Item (444, 199, "Item4");
list.add(item4);
Item item5 = new Item (555, 14, "Item5");
list.add(item5);
Item item6 = new Item (666, 40, "Item6");
list.add(item6);
list.add(item6);
list.add(item6);
list.add(item2);
list.add(item3);
list.add(item3);
list.add(item3);
}
public ArrayList getList()
{
return list;
}
public ArrayList getCopy(ArrayList listToCopy)
{
ArrayList copy = new ArrayList(numOfItemsInStore);
if (listToCopy.isEmpty())
System.out.println("This list is Empty");
else
{
Object[] listArray = listToCopy.toArray();
for (int i = 0; i < listArray.length; i++)
{
Item item = (Item) listArray[i];
copy.add(item);
}
}
return copy;
}
}
here is the Item class
public class Item
{
private int identifier;
private int price;
private String name;
public Item (int id, int price , String name)
{
this.identifier = id;
this.name = name;
this.price = price;
}
public int getIdentifier()
{
return identifier;
}
public int getPrice()
{
return price;
}
public String getName()
{
return name;
}
}
Okay first of all I would suggest to use a Set to remove duplicates...
public void print(ListOfItems storeList)
{
// At this point make sure that "getCopy(ArrayList <Item> listToCopy)" creates a deep copy!
ArrayList <Item> copyOfList = storeList.getCopy(storeList.getList());
// For using this statement make sure that you override "equals" in the "Item" class!
Set <Item> uniqueItems = new HashSet <Item> (copyOfList);
for(Item item : uniqueItems)
{
// Code for usage of each single item
}
}
...This is just one possible approach of solution, but makes sure that you overrides equals
and that your function getCopy()
creates a deep copy!
Thanks to Coderino Javarino , of course you must override the equals
and the hashCode
method not the toString
method!
One option to override the equals
method...
@Override public boolean equals(Object object)
{
if(this == object)
{
return true;
}
if(object == null || getClass() != object.getClass())
{
return false;
}
Item item = (Item) object;
return Objects.equals(this.name, item.name) &&
this.identifier == item.identifier &&
this.price == item.price;
}
And here an option to create a deep copy...
public ArrayList getCopy(ArrayList <Item> listToCopy)
{
if(null == listToCopy)
{
// Handle this option too
}
ArrayList <Item> copy = new ArrayList(listToCopy.size());
for(Item item : listToCopy)
{
// It is important that your class "Item" contains a copy constructor
copy.add(new Item(item));
}
return copy;
}
According to your code, I guess item 6 and item 3 were missed from your final cop list. Because remove action is not correct.
At the begin for-loop, the initial state of 3 variables are:
The state of 3 variables above after outter for-loop finished round 6 (i=5):
Unluckily, when i=6 and j=7, we found that "item 6" is duplicate again, and the copy list removed it. <- the problem is here.
We are absolutely able to explain why "item 3" lost with the same idea. It happened when i=10, j=11.
And how to fix it? If you still want to use 2 for-loop, you can implement the strategy below:
init copy list is empty
init originalitem as copy of your list
for item in originalItem
isExist = false
for copy list
if item in copy
isExist = true
break
if isExist = false
copy add item
But, there are many ways to remove effectively a duplicate element in a list, rather than using 2 for-loop strategy.
else
{
Object[] originalItems = list.toArray();
ArrayList copy = new ArrayList(list.size());
for (int i = 0; i < originalItems.length; i++)
{
Item item = (Item) originalItems[i];
if (copy.contains(item) == false)
{
copy.add(item);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.