Java 输入ArrayList的每个实例化对象是否使用对该ArrayList的相同引用?
我有一个平面文件读取器类,它从dat文件中读取数据,创建个人、客户和产品对象,这些对象存储在其唯一的arraylist中,我必须将其用于getInvoice方法。从发票dat文件输入新属性时,我仅为从发票dat文件读取的产品创建一个新产品列表。这似乎工作正常,但是每个发票对象上的某些产品属性正在更改 当以product arraylist作为字段实例化新发票对象时,这会创建对添加到下面代码中的产品列表的引用,还是创建该列表的副本?如果它只是一个参考,为什么当我阅读每个发票对象中的产品列表时,每个发票中的产品对象数量(而不是所有产品)是正确的?另外,如果在创建发票对象(其中包含产品列表作为字段)后清除新产品列表,则我所有发票中的产品列表都为空。为什么会这样?如果arraylist不起作用,我还能怎么做?谢谢,如果需要,我可以添加更多代码Java 输入ArrayList的每个实例化对象是否使用对该ArrayList的相同引用?,java,arraylist,reference,Java,Arraylist,Reference,我有一个平面文件读取器类,它从dat文件中读取数据,创建个人、客户和产品对象,这些对象存储在其唯一的arraylist中,我必须将其用于getInvoice方法。从发票dat文件输入新属性时,我仅为从发票dat文件读取的产品创建一个新产品列表。这似乎工作正常,但是每个发票对象上的某些产品属性正在更改 当以product 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; }