Reputation: 5
I have been encountering a specific problem where only the first item in Arraylist is included when it comes to iterating each element in Arraylist (to search/to remove). That means that the second until n-1 iteams won't be found whenever I try to iterate. Edited: currently improving my code.
You could try the following program. It is perfectly working only when adding the first record of the order: I can remove and search its values. However, when adding the second order: I can not remove and search its values, rather it is not found.
Source code
import java.util.*;
import java.io.*;
public class TestOrders {
public static void main(String[] args) throws FileNotFoundException, IOException, NoSuchElementException {
File afile = new File("order.txt");
FileOutputStream outFile = new FileOutputStream("order.txt");
ObjectOutputStream outStream = new ObjectOutputStream(outFile);
FileInputStream inFile = new FileInputStream("order.txt");
ObjectInputStream inStream = new ObjectInputStream(inFile);
//Create an arraylist of order
ArrayList<Order> theorder = new ArrayList<>();
Scanner scan = new Scanner(System.in);
System.out.println("Welcome to Order");
System.out.println("Please choose an option (1-5): ");
int choice = 0;
try {
while (choice != 5) {
//A list of options
System.out.println("\n1. Add a new order: ");
System.out.println("2. Search an order: ");
System.out.println("3. Compute sum of all orders:");
System.out.println("4. Remove an order: ");
System.out.println("5. Exit: ");
//prompt user
System.out.print("Pick a number: ");
if (scan.hasNextInt()) {
choice = scan.nextInt();
}
switch(choice) {
case 1:
addNewOrder(outStream, theorder);
break;
case 2:
searchOrder(outStream, inStream, theorder);
break;
case 3:
computeSum(afile, theorder);
break;
case 4:
removeOrder(outStream, inStream, theorder);
break;
case 5:
System.exit(0);
break;
default:
System.out.println("Please enter from (1-5)");
}
}
} catch (IOException | InputMismatchException ex) {
System.out.println(ex);
} finally {
if (choice == 5) {
scan.close();
outStream.close();
inStream.close();
}
}
}
public static void addNewOrder(ObjectOutputStream outStream, ArrayList<Order> theorder) throws IOException {
Scanner input = new Scanner(System.in);
Order anorder = new Order();
System.out.print("Enter the order ID: ");
anorder.setOrderID(input.nextInt());
input.nextLine();
System.out.print("Enter the customer name: ");
anorder.setCustomerName(input.nextLine());
System.out.print("Enter the order (meal/drink): ");
anorder.setOrderType(input.nextLine());
System.out.print("Enter the order price: ");
anorder.setPrice(input.nextDouble());
if(theorder.size() <= 1000) {
theorder.add(anorder);
outStream.writeObject(anorder);
System.out.println("Order information saved.\n");
} else {
System.out.println("There is not enough space.");
}
}
public static void searchOrder(ObjectOutputStream outStream, ObjectInputStream inStream, ArrayList<Order> theorder) throws FileNotFoundException {
Scanner input = new Scanner(System.in);
Order o = new Order();
System.out.println("Please enter a customer ID: ");
int custID = input.nextInt();
for (Order or : theorder) {
if(or.getOrderID() == custID) {
System.out.println(or.toString());
break;
} else {
System.out.println("No matching record found");
break;
}
}
}
public static void computeSum(File aFile, ArrayList<Order> theorder) throws FileNotFoundException, IOException {
double sum = 0;
for (Order o : theorder) {
sum += o.getPrice();
}
sum = (double) Math.round(sum*100)/100;
System.out.println("The total sum of price for " + theorder.size() + " orders is " + sum);
}
public static void removeOrder(ObjectOutputStream outStream, ObjectInputStream inStream, ArrayList<Order> theorder) {
Iterator<Order> iterator = theorder.iterator();
Scanner input = new Scanner(System.in);
System.out.println("Enter the order ID to remove: ");
int custID = input.nextInt();
while (iterator.hasNext()) {
Order anorder = iterator.next();
if(anorder.getOrderID() == custID) {
theorder.remove(anorder);
System.out.println(anorder.toString());
break;
} else {
System.out.println("Not found\n");
break;
}
}
for (Order o : theorder) {
System.out.println(o.toString());
}
}
}
Order class
import java.util.*;
import java.io.*;
public class Order implements Serializable {
private int orderID;
private String customerName;
private String orderType;
private double price;
public Order() {
}
public Order(int orderID, String customerName, String orderType, double price) {
this.orderID = orderID;
this.customerName = customerName;
this.orderType = orderType;
this.price = price;
}
public int getOrderID() {
return orderID;
}
public void setOrderID(int orderID) {
this.orderID = orderID;
}
public String getCustomerName() {
return this.customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getOrderType() {
return this.orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String toString() {
return this.orderID + " " + this.customerName + " " + this.orderType + " " + this.price + "\n";
}
}
This part is where I am struggling. I had tried using iterator but it got the same result, second item cannot be iterated/found.
for (Order o : theorder) {
if(o.getOrderID() == orderIDSearch) {
theorder.remove(orderIDSearch);
System.out.println("Order has been successfully removed");
continue;
} else {
System.out.println("Not found ");
break;
}
}
What should I do to fix this problem? is there any way it can be solved?
Upvotes: 0
Views: 63
Reputation: 1234
for ( Order o : theorder ) {
if ( o.getOrderID() == orderIDSearch ) {
theorder.remove(orderIDSearch);
System.out.println("Order has been successfully removed");
continue;
} else {
System.out.println("Not found ");
break;
}
}
There are several problems here:
First, removal of an element of a collection whilst iterating across the collection requires a different technique than you are using. Generally, modifying a collection in the midst of iteration will result in a ConcurrentModificationException
.
Second, are multiple matches expected? If there is at most one match, the continue
should be a break
.
Third, one would expect the code to continue to following elements when a current element is not a match. That is, the break
should be a continue
, or better yet, should be removed entirely.
Fourth, its not clear that theorder.remove(orderIDSearch)
will do anything, unless the collection type has a remove
operation which takes a key value instead of an element value. For basic collection types (List
, Set
), the call won't do anything.
Here are two rewrites:
If the iterator supports remove:
Iterator<Order> orders = theorder.iterator();
boolean found = false;
while ( !found && orders.hasNext() ) {
if ( orders.next().getOrderID() == orderIDSearch ) {
found = true;
}
}
if ( found ) {
orders.remove();
System.out.println("Found and removed [ " + orderIDSearch + " ]");
} else {
System.out.println("Not found [ " + orderIDSearch + " ]");
}
If the iterator does not support remove, then:
boolean found = false;
for ( Order o : theorder ) {
if ( o.getOrderID() == orderIDSearch ) {
found = true;
break;
}
}
if ( found ) {
theorder.remove(orderIDSearch);
System.out.println("Found and removed [ " + orderIDSearch + " ]");
} else {
System.out.println("Not found [ " + orderIDSearch + " ]");
}
Note that this relies on remove
accepting a key as the parameter value.
Upvotes: 1
Reputation: 134
You are breaking the loop in for search in else condition. Why would you do that.. Remove the else part
Upvotes: 0