【问题标题】:Search arraylist of objects does not work搜索对象数组列表不起作用
【发布时间】:2020-02-21 22:30:58
【问题描述】:

我遇到了一个特定的问题,即在迭代 Arraylist 中的每个元素(搜索/删除)时只包含 Arraylist 中的第一项。这意味着每当我尝试迭代时,都不会找到第二个直到 n-1 个 itams。 已编辑:目前正在改进我的代码。

您可以尝试以下程序。 在添加订单的第一条记录时完美运行:我可以删除和搜索它的值。但是,添加第二个订单时:我无法删除和搜索它的值,而是找不到它。

源代码

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());
            }
    }
}

订单类

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";
    }
}

这部分是我苦苦挣扎的地方。我曾尝试使用迭代器,但结果相同,无法迭代/找到第二项。

                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;
                }
            }

我应该怎么做才能解决这个问题?有什么办法可以解决吗?

【问题讨论】:

    标签: java arraylist iterator


    【解决方案1】:
    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;
        }
    }
    

    这里有几个问题:

    首先,在遍历集合时删除集合的元素需要与您使用的不同的技术。通常,在迭代过程中修改集合会导致ConcurrentModificationException

    其次,是否需要多个匹配项?如果最多匹配一个,continue 应该是break

    第三,当当前元素不匹配时,人们会期望代码继续跟随元素。也就是说,break 应该是 continue,或者更好的是,应该完全删除。

    第四,不清楚theorder.remove(orderIDSearch) 是否会做任何事情,除非集合类型有一个remove 操作,它采用键值而不是元素值。对于基本集合类型(ListSet),调用不会做任何事情。

    这里有两个重写:

    如果迭代器支持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 + " ]");
    }
    

    如果迭代器不支持remove,那么:

    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 + " ]");
    }
    

    请注意,这依赖于remove 接受一个键作为参数值。

    【讨论】:

    • 非常感谢您的回答、cmets 和信息丰富的方法。谢谢你的帮助:)
    【解决方案2】:

    您在 else 条件下打破了 for search 的循环。 你为什么要这样做..删除else部分

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 2011-10-04
      • 2017-11-14
      • 2016-10-23
      • 2011-10-04
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      相关资源
      最近更新 更多