Проблема с присвоением ссылки на массив
Почему, если во втором конструкторе PizzaType при значении true параметра isLinked, по идее должен не создаваться массив ingredients, а должна передаваться ссылка на массив ingredients объекта типа PizzaType, на основе которого создан другой объект типа PizzaType, и таким образом у двух объектов будут общие ингредиенты (т.е. они будут ссылаться на один и тот же массив), то впоследствии, когда я создаю объект sea на основе classic и к массиву sea добавляю некоторые элементы, а потом отображаю сначала массив ingredients sea, а затем массив ingredients classic, то массив classic не содержит того, что содержит массив sea.
Я вот думаю, если в таком случае это не общий массив, то как тогда был создан массив объекта sea (ведь в конструкторе класса при значении true параметра isLinked не выделяется память для его собственного массива, а лишь передается ссылка на массив другоо объекта).
Просто я хочу, чтобы при установленным в true параметре isLinked объекты имели один общий массив, а при false - у sea создавался свой независимый массив на основе classic.
class PizzaType {
String ingredients[];
private double price;
PizzaType(double price, String...v) {
ingredients = new String[v.length];
for(int i = 0; i < v.length; ++i) {
ingredients[i] = v[i];
}
this.price = price;
}
PizzaType(PizzaType pt, boolean isLinked) {
if(isLinked) ingredients = pt.ingredients;
else {
ingredients = new String[pt.ingredients.length];
for(int i = 0; i < ingredients.length; ++i) ingredients[i] = pt.ingredients[i];
}
price = pt.getPrice();
}
void showIngredients() {
for(int k = 0; k < ingredients.length; ++k)
System.out.println(ingredients[k]);
}
void setPrice(double price) {
this.price = price;
}
double getPrice() {
return price;
}
void addIng(String...ing) {
int k, len = ingredients.length;
String[] a = new String[len + ing.length];
for(k = 0; k < len; ++k) {
a[k] = ingredients[k];
}
for(k = len; k < len + ing.length; ++k) {
a[k] = ing[k - len];
}
ingredients = a;
}
public static void main(String args[]) {
// Classic Pizza
PizzaType classic = new PizzaType(200, "cheese", "sausage", "tomato");
// Vegetable Pizza
PizzaType vegetable = new PizzaType(280, "tomato", "onion", "olives", "cucumber");
// Mix based on Classic without a link
PizzaType mix = new PizzaType(classic, false);
mix.addIng("mushrooms", "cucumber");
System.out.println("Mix pizza ingredients:");
mix.showIngredients();
System.out.println("Classic pizza ingredients:");
classic.showIngredients();
// Sea based on Vegetable with a link
PizzaType sea = new PizzaType(vegetable, true);
sea.addIng("fish", "squid");
System.out.println("Sea pizza ingredients:");
sea.showIngredients();
System.out.println("Vegetable pizza ingredients:");
vegetable.showIngredients();
}
Результат кода:
Mix pizza ingredients:
cheese
sausage
tomato
mushrooms
cucumber
Classic pizza ingredients:
cheese
sausage
tomato
Sea pizza ingredients:
tomato
onion
olives
cucumber
fish
squid
Vegetable pizza ingredients:
tomato
onion
olives
cucumber
Ответы (1 шт):
Вы в конструкторе используете ingredients = pt.ingredients, что присваивает ссылку на массив ингредиентов из объекта pt массиву ингредиентов этого класса. Вы не скопировали массив, а просто присвоили ссылку на другой массив.
Решение:
- Поэлементное копирование массива
- Вызов pt.ingredients.clone(), что склонирует массив и "отделит" его от другого списка ингредиентов
Если необходимо "связать" два массива, то ошибка происходит в методе addIng. Здесь Вы создаете новый массив, соответственно ссылка на предыдущий массив заменяется новой, и он никак не связан с тем, что был присвоен в конструкторе.
Самый удобный способ исправить это - использовать List в качестве коллекции для хранения ингредиентов. При добавлении новых ингредиентов в список его ссылка не будет меняться.
Таким образом код должен быть таким:
class PizzaType {
List<String> ingredients;
private double price;
PizzaType(double price, String...v) {
ingredients = new ArrayList(v);
this.price = price;
}
PizzaType(PizzaType pt, boolean isLinked) {
if(isLinked) ingredients = pt.ingredients;
else ingredients = new ArrayList(pt.ingredients);
price = pt.getPrice();
}
void showIngredients() {
for(int k = 0; k < ingredients.size(); ++k)
System.out.println(ingredients[k]);
}
void setPrice(double price) {
this.price = price;
}
double getPrice() {
return price;
}
void addIng(String...ing) {
for(String i : ing) {
ingredients.add(i);
}
}