克隆与仅仅分配值有何不同(为什么要费心实现接口 Cloneable)?
How is cloning different from just assigning values (why bother implementing interface Cloneable)?
我正在尝试创建 class 的深层副本。这是我试图复制的 class,最后一种方法是复制方法:
import java.util.ArrayList;
import java.util.List;
public class catalog implements Cloneable{
List<product> cat = new ArrayList<>();
int counter;
final int capacity = 2;
public void addProduct(product x){
cat.add(x);
}
public void addProduct(String name, int id, int price, int stock) throws Exception{
for(int i = 0; i < cat.size(); i++){
product temp = cat.get(i);
if(temp.name == name){
temp.stock = temp.stock + stock;
return;
}
if(temp.id == id){
System.out.println("Product with this ID already exists");
return;
}
}
if(cat.size() >= capacity){
//throw new customException("Not enough capacity");
throw new customException();
}
product temp = new product();
temp.name = name;
temp.id = id;
temp.price = price;
temp.stock = stock;
cat.add(temp);
}
public void showSelection(){
for(product temp : cat){
System.out.println("Product " + temp.name + " ID: " + temp.id
+ " Price: " + temp.price + " In stock: " + temp.stock);
}
}
public void removeFromStock(String name){
for(int i = 0; i < cat.size(); i++){
product temp = cat.get(i);
if(temp.name == name){
temp.stock = temp.stock - 1;
cat.set(i, temp);
}
}
}
public Object clone(){
catalog b = new catalog();
for(int i = 0; i <= cat.size(); i++){
product temp, temp1;
temp1 = cat.get(i);
temp = (product)temp1.clone();
b.addProduct(temp);
}
return b;
}
}
这是主要内容:
public class testMoney {
public static void main(String[] args) {
automatasklase test = new automatasklase();
test.addMoney(50);
System.out.println(test.getMoney());
product cola = new product();
cola.id = 1;
cola.price = 2;
cola.name = "Cola";
productsExpire Milk = new productsExpire();
Milk.name = "Milk";
Milk.id = 2;
Milk.price = 10;
Milk.stock = 10;
Milk.isExpired = true;
catalog menu = new catalog();
menu.addProduct(cola);
menu.addProduct(Milk);
menu.showSelection();
try{
menu.addProduct("Pepsi" ,3, 5, 108);
}catch(Exception e){
System.out.println("Exception occured = " +e);
}
try {
menu.addProduct("Cola", 1, 3, 7);
} catch (Exception e) {
System.out.println("Exception occured = " + e.getMessage());
}
menu.showSelection();
test.buyProduct(menu, 2);
System.out.println(test.getMoney());
menu.showSelection();
Milk.isAvailable();
product copyy = (product)cola.clone();
System.out.println("-------------");
System.out.println(cola.id + cola.name + cola.price + cola.stock);
System.out.println(copyy.id + copyy.name + copyy.price + copyy.stock);
// BELOW THE PROBLEM OCCURS!!!
catalog newtest = (catalog) menu.clone();
// ABOVE THE IS THE PROBLEM!!!!
}
}
问题如下:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at AutomatasA.catalog.clone(catalog.java:58)
at AutomatasA.testMoney.main(testMoney.java:46)
您会注意到我已经在目录本身的克隆方法中克隆了一个产品 class 对象,但正如您可能注意到的那样,主 class 已经对其进行了测试并且可以正常工作,所以 class 产品的克隆是成功的。
你能看出问题所在吗?我知道在编码礼仪方面也会有很多小错误,也许做事的方法更简单,但我只是一个初学者。我必须实现深拷贝,它必须意味着什么,所以克隆产品 class 是不够的,我想创建一个克隆整个目录的方法,所以如果机器被替换为较新的,您可以使用该方法。
顺便说一句,整个项目都在为虚拟零食机创建一个代码,就像你输入钱,按你想要的项目的数字,然后得到它。
感谢您的帮助!
您的异常是由这一行引起的:
for(int i = 0; i <= cat.size(); i++){
应该是
for(int i = 0; i < cat.size(); i++){
但是你真的不应该那样实现你自己的深度克隆。如果你想要一个副本,为它创建一个单独的方法,或者一个复制构造函数。
我正在尝试创建 class 的深层副本。这是我试图复制的 class,最后一种方法是复制方法:
import java.util.ArrayList;
import java.util.List;
public class catalog implements Cloneable{
List<product> cat = new ArrayList<>();
int counter;
final int capacity = 2;
public void addProduct(product x){
cat.add(x);
}
public void addProduct(String name, int id, int price, int stock) throws Exception{
for(int i = 0; i < cat.size(); i++){
product temp = cat.get(i);
if(temp.name == name){
temp.stock = temp.stock + stock;
return;
}
if(temp.id == id){
System.out.println("Product with this ID already exists");
return;
}
}
if(cat.size() >= capacity){
//throw new customException("Not enough capacity");
throw new customException();
}
product temp = new product();
temp.name = name;
temp.id = id;
temp.price = price;
temp.stock = stock;
cat.add(temp);
}
public void showSelection(){
for(product temp : cat){
System.out.println("Product " + temp.name + " ID: " + temp.id
+ " Price: " + temp.price + " In stock: " + temp.stock);
}
}
public void removeFromStock(String name){
for(int i = 0; i < cat.size(); i++){
product temp = cat.get(i);
if(temp.name == name){
temp.stock = temp.stock - 1;
cat.set(i, temp);
}
}
}
public Object clone(){
catalog b = new catalog();
for(int i = 0; i <= cat.size(); i++){
product temp, temp1;
temp1 = cat.get(i);
temp = (product)temp1.clone();
b.addProduct(temp);
}
return b;
}
}
这是主要内容:
public class testMoney {
public static void main(String[] args) {
automatasklase test = new automatasklase();
test.addMoney(50);
System.out.println(test.getMoney());
product cola = new product();
cola.id = 1;
cola.price = 2;
cola.name = "Cola";
productsExpire Milk = new productsExpire();
Milk.name = "Milk";
Milk.id = 2;
Milk.price = 10;
Milk.stock = 10;
Milk.isExpired = true;
catalog menu = new catalog();
menu.addProduct(cola);
menu.addProduct(Milk);
menu.showSelection();
try{
menu.addProduct("Pepsi" ,3, 5, 108);
}catch(Exception e){
System.out.println("Exception occured = " +e);
}
try {
menu.addProduct("Cola", 1, 3, 7);
} catch (Exception e) {
System.out.println("Exception occured = " + e.getMessage());
}
menu.showSelection();
test.buyProduct(menu, 2);
System.out.println(test.getMoney());
menu.showSelection();
Milk.isAvailable();
product copyy = (product)cola.clone();
System.out.println("-------------");
System.out.println(cola.id + cola.name + cola.price + cola.stock);
System.out.println(copyy.id + copyy.name + copyy.price + copyy.stock);
// BELOW THE PROBLEM OCCURS!!!
catalog newtest = (catalog) menu.clone();
// ABOVE THE IS THE PROBLEM!!!!
}
}
问题如下:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at AutomatasA.catalog.clone(catalog.java:58)
at AutomatasA.testMoney.main(testMoney.java:46)
您会注意到我已经在目录本身的克隆方法中克隆了一个产品 class 对象,但正如您可能注意到的那样,主 class 已经对其进行了测试并且可以正常工作,所以 class 产品的克隆是成功的。
你能看出问题所在吗?我知道在编码礼仪方面也会有很多小错误,也许做事的方法更简单,但我只是一个初学者。我必须实现深拷贝,它必须意味着什么,所以克隆产品 class 是不够的,我想创建一个克隆整个目录的方法,所以如果机器被替换为较新的,您可以使用该方法。
顺便说一句,整个项目都在为虚拟零食机创建一个代码,就像你输入钱,按你想要的项目的数字,然后得到它。
感谢您的帮助!
您的异常是由这一行引起的:
for(int i = 0; i <= cat.size(); i++){
应该是
for(int i = 0; i < cat.size(); i++){
但是你真的不应该那样实现你自己的深度克隆。如果你想要一个副本,为它创建一个单独的方法,或者一个复制构造函数。