Java 输入ArrayList的每个实例化对象是否使用对该ArrayList的相同引用?

Java 输入ArrayList的每个实例化对象是否使用对该ArrayList的相同引用?,java,arraylist,reference,Java,Arraylist,Reference,我有一个平面文件读取器类,它从dat文件中读取数据,创建个人、客户和产品对象,这些对象存储在其唯一的arraylist中,我必须将其用于getInvoice方法。从发票dat文件输入新属性时,我仅为从发票dat文件读取的产品创建一个新产品列表。这似乎工作正常,但是每个发票对象上的某些产品属性正在更改 当以product arraylist作为字段实例化新发票对象时,这会创建对添加到下面代码中的产品列表的引用,还是创建该列表的副本?如果它只是一个参考,为什么当我阅读每个发票对象中的产品列表时,每个

我有一个平面文件读取器类,它从dat文件中读取数据,创建个人、客户和产品对象,这些对象存储在其唯一的arraylist中,我必须将其用于getInvoice方法。从发票dat文件输入新属性时,我仅为从发票dat文件读取的产品创建一个新产品列表。这似乎工作正常,但是每个发票对象上的某些产品属性正在更改

当以product arraylist作为字段实例化新发票对象时,这会创建对添加到下面代码中的产品列表的引用,还是创建该列表的副本?如果它只是一个参考,为什么当我阅读每个发票对象中的产品列表时,每个发票中的产品对象数量(而不是所有产品)是正确的?另外,如果在创建发票对象(其中包含产品列表作为字段)后清除新产品列表,则我所有发票中的产品列表都为空。为什么会这样?如果arraylist不起作用,我还能怎么做?谢谢,如果需要,我可以添加更多代码

public ArrayList<Invoice> getInvoices() {
    readPersons();
    readCustomers();
    readProducts();
    Scanner sc = null;

    try {
        sc = new Scanner(new File("data/Invoices.dat"));
        sc.nextLine(); 

        while (sc.hasNextLine()) {
            ArrayList<Product> product = new ArrayList<Product>();
            String line = sc.nextLine(); 
            String data[] = line.split(";"); 
            String invoiceCode = data[0].trim();
            String customerCode = data[1].trim();
            Customer customer = null;
            for(Customer aCustomer: customerList) {
                if (customerCode.equals(aCustomer.getCustomerCode())) {
                    customer = aCustomer;
                    break;
                }
            }
            String personCode = data[2].trim();
            Person person = null;
            for(Person aPerson: personList) {
                if (personCode.equals(aPerson.getPersonCode())) {
                    person = aPerson;
                    break;
                }
            }
            String invoiceDate = data[3];
            String products[] = data[4].split(",");
                for (int i = 0; i < products.length; i++) {
                    String productData[] = products[i].split(":");
                    for(Product aProduct: productList) {
                        if (aProduct.getProductCode().equals(productData[0])) {
                            aProduct.setInvoiceDate(this.getDateTime(invoiceDate));
                            if (productData.length == 1) {
                                aProduct.setQuantity(1);
                                product.add(aProduct);
                            } else if (productData.length == 2) {
                                aProduct.setQuantity(Integer.parseInt(productData[1]));
                                product.add(aProduct);
                            } else if (productData.length == 3) {
                                aProduct.setQuantity(Integer.parseInt(productData[1]));
                                for(Product anotherProduct: product) {
                                    if (anotherProduct.getProductCode() == productData[2]) {
                                        aProduct.setParkingPassCount(anotherProduct.getQuantity());
                                        break;
                                    }
                                }
                                product.add(aProduct);
                            }
                            break;
                        }
                    }
                }

            // Creates an Invoice object
            Invoice invoice = new Invoice(invoiceCode, invoiceDate, customer, person, product);

            // Adds the Invoice object into Invoice ArrayList
            invoiceList.add(invoice);   

        }
        sc.close();
        return invoiceList;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return null;
    }
}
public DateTime getDateTime(String Date){
    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
    DateTime dateTime = formatter.parseDateTime(Date);
    return dateTime;
} 
public ArrayList getInvoices(){
读者();
readCustomers();
readProducts();
扫描仪sc=空;
试一试{
sc=新扫描仪(新文件(“data/Invoices.dat”);
sc.nextLine();
while(sc.hasNextLine()){
ArrayList产品=新的ArrayList();
字符串行=sc.nextLine();
字符串数据[]=行。拆分(“;”);
字符串invoiceCode=数据[0]。trim();
字符串customerCode=data[1].trim();
客户=空;
for(客户客户客户:客户列表){
if(customerCode.equals(aCustomer.getCustomerCode())){
顾客=针灸师;
打破
}
}
字符串personCode=data[2]。trim();
Person=null;
对于(个人:个人列表){
if(personCode.equals(aPerson.getPersonCode())){
人=人;
打破
}
}
字符串invoiceDate=数据[3];
字符串产品[]=数据[4]。拆分(“,”);
对于(int i=0;i
不太清楚你在问什么,但让我们看看;我想你的观点是:

您的类中有一些字段(发票列表);您的方法只是将新的Invoice对象附加到该列表中

假设invoiceList对象未被清除,或其他一些代码调用

invoiceList = new ArrayList<>()
invoiceList=newarraylist()
重复地,代码总是使用相同的
ArrayList对象

乍一看,您的总体设计可能会有所改进。您可以看到,将新对象添加到同一列表意味着您依赖于副作用。但另一方面,您的方法也返回您处理的列表。你应该做一个或另一个;但不是两者都有

因此,选项一-依赖于使用字段,如:

class InvoiceCollector {
   private final List<Invoice> invoices = new ArrayList<>();

   public void addNewInvoices() {
     ... reads data from file and adds new objects to invoices

   public List<Invoice> getCurrentInvoices() {
     return new ArrayList<>(invoices);
类发票收集器{
私有最终清单发票=新ArrayList();
公共作废addNewInvoices(){
…从文件读取数据并将新对象添加到发票
公共列表getCurrentInvoices(){
返回新的ArrayList(发票);
(返回该列表的副本可防止接收该列表引用的代码**从外部对其进行操作)

选项二:只返回最后收集的发票(并避免在该类上有一个字段):

公共发票列表(){
列出发票=。。。
…方法中的所有代码
退回发票;
}
最后:

  • 阅读单层抽象原则。你糟糕的方法是做
    public List<Invoice> collectInvoices() {
      List<Invoice> invoices = ...
      ... all the code you have in your method
      return invoices;
    }