Изменение списка не должно влиять на его объект - Java - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть класс Butterfly:

public class Butterfly extends Insect {

/**
 * Field to hold the list of colors that a butterfly object is.
 */
private List<String> colors;

/**
 * Constructor to initialize the fields.
 * 
 * @param species - Species of Butterfly.
 */
public Butterfly(String species, List<String> colors) {
    super(species);
    this.colors = colors;
}

/**
 * Constructor to initialize an existing Butterfly object.
 * 
 * @param butterfly - Butterfly object
 */
public Butterfly(Butterfly butterfly) {
    this(butterfly.getSpecies(), butterfly.getColors());
}

/**
 * Getter for the colors of the butterfly. 
 * 
 * @return the colors - Colors of the butterfly.
 */
public List<String> getColors() {
    return colors;
}

@Override
public String toString() {
    return getSpecies() + " " + colors;
}

}

и тестовый пример JUnit, который вызывает у меня проблемы:

@Test
void butterfly_immutable() {
    List<String> colors = new ArrayList<>();
    Collections.addAll(colors, "orange", "black", "white");

    Butterfly b1 = new Butterfly("Monarch", colors);
    Butterfly b2 = new Butterfly(b1);

    // Modifying the original color list should not affect b1 or b2.
    colors.set(0, "pink");

    // Modifying the colors returned by the getters should not affect b1 or b2
    List<String> b1Colors = b1.getColors();
    b1Colors.set(1, "lime");
    List<String> b2Colors = b2.getColors();
    b2Colors.set(1, "cyan");

    assertTrue(sameColors(List.of("orange", "black", "white"), b1.getColors()));    
    assertTrue(sameColors(List.of("orange", "black", "white"), b2.getColors()));    
}   

Мой вопрос: как предотвратить изменение цвета объект Butterfly, если сами цвета изменены. Я пытался использовать List.of, List.copyOf, Collections.unmodifiableList, и я просто не могу понять это. Любая помощь будет принята с благодарностью. Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 22 февраля 2020

Измените строку

this.colors = colors;

на

this.colors = List.copyOf(colors);

Это сделает поле Butterfly.colors неизменяемой копией List, переданной в конструктор.

Если вы хотите, чтобы Butterfly можно было модифицировать другими способами, вы могли бы сделать изменяемую копию в конструкторе, но вам также пришлось бы копировать в «получателе».

this.colors = ArrayList<>(colors);

public List<String> getColors() {
    return List.copyOf(colors);
}

(Технически конструктор ArrayList можно победить, но обычно вам не нужно об этом беспокоиться.)

0 голосов
/ 22 февраля 2020

Изменение метода getColors () класса Butterfly:

public List<String> getColors() {
    return colors == null ? null : new ArrayList<>(colors);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...