Подтвердить что ты не робот

Можно ли инициализировать логические массивы в цикле for?

Просто нашел этот вопрос SO, который возник, чтобы решить мою проблему с инициализацией логического массива инициализации булевого массива в java. Однако, хотя он дал мне код, который будет работать, искатель не пытался использовать код, который я запускал, который не работал, и я действительно хотел бы знать, почему он не работает. Это был код, который я пытался:

Boolean[] array = new Boolean[5];
for(Boolean value : array) {
    value = false;
}

Это функциональный код из этого другого вопроса:

Boolean[] array = new Boolean[5];
Arrays.fill(array, Boolean.FALSE);

Мне просто интересно, почему подход for loop не работает?

4b9b3361

Ответ 1

Boolean[] array = new Boolean[5];
for(Boolean value : array) {
    value = false;
}

Java, усиленный для цикла, использует итератор для прохождения массива. Итератор возвращает ссылку на объект, но java передает ссылку по значению, поэтому вы не можете изменить то, на что ссылаетесь, что вы пытаетесь сделать с помощью value = false.

EDIT:
Как оказалось, для обычного массива вместо преобразования в List и использования итератора java делает следующее:

for (int i = 0; i < array.length; i++) 
{
    Boolean value = array[i]; //here how we get the value that referred to 
    ...                       //in the enchanced for loop  
}

Пока мы не используем итератор, тот факт, что Java передает ссылки по стоимости, все еще объясняет, что происходит здесь. КОНЕЦ РЕДАКТИРОВАНИЯ

Если бы это был массив объектов с определенными членами экземпляра, вы могли бы изменять указанные члены, но не то, что ссылается на объект, сам.

Как и другие, чтобы обойти это, просто используйте регулярный цикл и вручную назначьте значения индексированным слотам в массиве, то есть:

Boolean[] b_values = new Boolean[5];
for(int i = 0; i < b_values.length; i++) 
{
    b_values[i] = Boolean.FALSE; 
}

Ответ 2

Причина, по которой код не был запущен, заключается в том, что, когда вы упомянули, что

Boolean[] array = new Boolean[5];
for(Boolean value : array) {
    value = false;
}

Фактически вы создаете новый ссылочный тип, называемый "Array of Boolean", и он содержит только ссылки на пять объектов булевого класса, но объект не существует, поскольку вы их не создали.

Пока во втором коде

Boolean[] array = new Boolean[5];
Arrays.fill(array, Boolean.FALSE);

Вы используете кешированный объект класса Boolean и добавляете его в массив, который вы создали, используя класс java.util.Arrays. Boolean - это класс-оболочка в java, и только два возможных значения могут быть возможны как true, так и false, чтобы избежать накладных расходов при их создании. Java уже создает их для вас и делает их доступными для использования.

Ответ 3

value = true; внутренне value = new Boolean (true); т.е. он создает новый объект в пуле. Объект value ссылается на этот Boolean object.Wrapper классы неизменяемы.

enter image description here

Ответ 4

Да Boolean[] можно инициализировать в цикле for. Для этого вам нужно установить значение с помощью индекса массива, а не для цикла. Посмотрите на следующий цикл.

Boolean[] array = new Boolean[5];
for(int i=0;i<array.length;i++) {
    array[i] = Boolean.FALSE;
}

Ответ 5

Потому что value - это копия массива element, а не фактический элемент в массиве.

Boolean[] array = new Boolean[5];    
    for (int i = 0; i < array.length; i++) {
             array[i]= false;           
    }

Только для справки: Как для каждого работает

Ответ 6

Это массив булевых ссылок без какого-либо реального объекта. Вам нужно это сделать.

Boolean[] array = new Boolean[5];
for(Boolean value : array) {
    value = new Boolean(false);
}

EDIT: Это не решает проблему. То же самое. В цикле for значение переменной не является ссылкой на исходный массив. Вот почему вам нужно делать.

Boolean[] array = new Boolean[5];    
for (int i = 0; i < array.length; i++) {
    array[i]= false;           
}

Ответ 7

Чтобы проиллюстрировать Changing the Reference и Changing the value of member if Reference, я попытался с классом User defined, разместив здесь то, что я пробовал, и наблюдение -thanks @SteveP

//Случай 1 Попытка изменить ссылку

    Boolean[] array1 = new Boolean[5];
    Arrays.fill(array1, Boolean.FALSE);
    for(Boolean value : array1) { // Warning here The value of the local variable value is not used
        value = Boolean.TRUE;
    }

    System.out.println(" Elements ==> "+array1[0]+" -  "+array1[1]);

это выведет Элементы == > false - false, ссылка не сможет изменить

Случай 2 Попытка изменить ссылку на определенный пользователем класс

        MyBool[] array3 = new MyBool[5];
    MyBool boolInst2=new MyBool( Boolean.FALSE);
    MyBool boolNew=new MyBool( Boolean.TRUE);

    Arrays.fill(array3,boolInst2 );
    for(MyBool value : array3) {  // Warning here The value of the local variable value is not used
        value = boolNew;
    }
    System.out.println(" Elements ==> "+array3[0].flag+" -  "+array3[1].flag);

это выведет Элементы == > false - false, ссылка не сможет изменить

Случай 3 Изменение значений элементов объекта (MyBool.value),

            MyBool[] array2 = new MyBool[5];
    MyBool boolInst=new MyBool( Boolean.FALSE);
    Arrays.fill(array2,boolInst );
    for(MyBool value : array2) {
        value.flag = Boolean.TRUE;
    }
    System.out.println(" Elements ==> "+array2[0].flag+" -  "+array2[2].flag);

это выведет Элементы == > true - true, значения обновляются

class MyBool{
    public Boolean flag;
    public MyBool(Boolean flag){
        this.flag=flag;
    }
}

Ответ 8

Короче: При перечислении массива, использующего цикл for, вы не можете изменить элемент коллекции, через который вы выполняете итерацию. Рассматривайте его как только для чтения.