JavaRush /Курсы /Модуль 1. Java Syntax /Нюансы работы с массивами

Нюансы работы с массивами

Модуль 1. Java Syntax
6 уровень , 1 лекция
Открыта

1. Массивы в памяти

Картинки в предыдущих примерах немного неточны.

При создании массивов (как и при создании строк) в памяти выделяются два блока памяти: один для хранения самого массива (контейнера), а второй — под переменную, которая хранит его адрес. Уточненная ситуация изображена на картинке ниже:

Массивы в памяти

Зеленым цветом изображен массив на 10 элементов типа int и переменная типа int[], которая хранит адрес (ссылку) массива типа int в памяти.

Для сравнения синим цветом обозначена обычная переменная типа int, которая хранит значение 199.

Чем-то напоминает хранение строк в памяти, не находите?

Верно, строки. И как при работе со строками, «переменные типа массив» можно присваивать друг другу:

Код Пояснение
int[] a = new int[10];
a[2] = 4;
a[7] = 9;
int[] b = a;

a[9] = b[2] + a[7];
Создаем массив на 10 элементов типа int.
В ячейку с индексом 2 записываем значение 4.
В ячейку с индексом 7 записываем значение 9.
В переменную b сохраняем адрес, который есть в переменной a.
Теперь a и b указывают на один и тот же объект-массив в памяти.
В ячейку с индексом 9 объекта-массива записываем сумму значений, которые хранятся в ячейках 2 (хранится 4) и 7 (хранится 9).

При этом объект-массив будет оставаться там, где и был, а переменные a и b будут хранить одинаковые адреса (ссылки) на один и тот же объект. Смотрите картинку:

Массивы в памяти 2

2. Работа с массивом более детально

Массив можно создать из абсолютно любого типа. Для этого нужно лишь после имени типа написать квадратные скобки. Общий вид создания массива будет такой:

тип[] имя = new тип[количество];

Где тип — это тип элементов (ячеек) массива, которые мы будем хранить в массиве. Имя — это имя переменной, по которой мы будем к массиву обращаться, а количество — это количество ячеек в массиве.

В примере выше приведена каноническая форма: создание переменной-массива и создание объекта-массива. На самом деле это две независимые конструкции.

Можно создать переменную-массив и объект-массив отдельно:

тип[] имя;
имя = new тип[количество];

И еще один немаловажный момент:

В качестве индекса массива и в качестве количества элементов массива могут выступать переменные и даже целые выражения.

Примеры:

Код Пояснение
int n = 100;
int[] a = new int[n];
Создание массива из n элементов
int n = 100;
int[] a = new int[n * 2 + 3];
Создание массива на 203 элемента
int n = 100;
int[] a = new int[n];
a[n-1] = 2;
a[n-2] = 3;
a[n/5] = a[n-1] + a[n-2]


// a[99] = 2;
// a[98] = 3;
// a[20] = a[99] + a[98];
Важно:
Кстати, обращаем ваше внимание, что если попробовать обратиться к ячейке массива по индексу, которого в массиве нет (в нашем случае это все целые числа, кроме чисел 0..99), программа аварийно завершится с ошибкой ArrayIndexOutOfBoundsException — индекс за границами массива.

3. Длина массива

Как вы увидели в предыдущем примере, можно отдельно создать переменную типа массив и потом где-то в коде присвоить ей значение (ссылку на объект-массив). Можно сделать даже так:

Код Пояснение
int[] array;
if (a < 10)
   array = new int[10];
else
   array = new int[20];
Создаем переменную-массив типа int[]
Если переменная a меньше 10,
то создать массив из 10 элементов.
Иначе
создать массив из 20 элементов

И как работать дальше с таким массивом? Как узнать, сколько в нем элементов?

Для этого у массива есть специальное свойство (переменная) — length. И узнать длину массива можно с помощью такого выражения:

array.length;

Где array — это имя переменной-массива, а length — это имя свойства у объекта-массива. Значение в свойстве length поменять нельзя: само свойство length можно присваивать другим переменным, но ему ничего присваивать нельзя (программа просто не скомпилируется).

Вот как можно продолжить предыдущий пример:

Код Пояснение
int[] array;
if (a < 10)
   array = new int[10];
else
   array = new int[20];
for (int i = 0; i < array.length; i++)
{
   System.out.println(array[i]);
} 
Создаем переменную-массив типа int[]
Если переменная a меньше 10,
то создать массив из 10 элементов.
Иначе
создать массив из 20 элементов
Цикл по всем элементам массива: от 0 и до длины array.length — 1

4. Резюмируем факты о массивах в Java

Давайте резюмируем известные факты о массивах:

Факт 1. Массив состоит из множества ячеек.

Факт 2. Доступ к конкретной ячейке идёт через указание её номера.

Факт 3. Все ячейки одного типа.

Факт 4. Начальное значение для всех ячеек — 0 и null (если в ячейке хранится адрес), false (для типа boolean). Подробнее о значениях по умолчанию вы узнаете в этой лекции.

Факт 5. String[] list – это просто объявление переменной: сам контейнер(объект-массив) еще не создан. Чтобы с ним можно было работать, нужно создать массив (контейнер) и положить его в эту переменную, а потом уже им пользоваться. См. пример ниже.

Факт 6. Когда мы создаём объект-массив (контейнер), нужно указать, какой он длины — сколько в нем ячеек. Это делается командой вида: new TypeName[n];

Факт 7. Длину массива можно узнать через свойство .length.

Факт 8. После создания массива нельзя поменять ни тип его элементов, ни их количество.

Код Пояснение
String s;
String[] list;
s равно null
list равно null
list = new String[10];
int n = list.length;
Переменная list хранит ссылку на объект – массив строк из 10 элементов.
n равно 10
list = new String[0];

Теперь list содержит массив из 0 элементов. Массив есть, но хранить элементы он не может.

list = null;
System.out.println(list[1]);
Будет сгенерировано исключение (ошибка программы) — программа аварийно завершится. list содержит пустую ссылку — null
list = new String[10];
System.out.println(list[10]);
Будет сгенерировано исключение (ошибка программы) — выход за границы массива.
Если list содержит 10 элементов/ячеек, то их разрешённые индексы: 0 1 2 3 4 5 6 7 8 9 — всего 10 штук.

6
Задача
Java Syntax Pro, 6 уровень, 1 лекция
Недоступна
Создаем массивы
В методе main проинициализируй переменные intArray и doubleArray массивами соответствующих типов, размер которых равен 10.
6
Задача
Java Syntax Pro, 6 уровень, 1 лекция
Недоступна
Четные и нечетные ячейки массива
В методе main(String[]) тебе нужно заполнить массив strings значениями. Если индекс массива чётный - присвоить значение "Чётный"(ноль - цифра чётная), иначе присвоить "Нечётный". Вывод текста в консоль в тестировании не участвует.
6
Задача
Java Syntax Pro, 6 уровень, 1 лекция
Недоступна
Работаем с элементами массива
Реализуй метод main(String[]), который меняет знак элемента массива array на противоположный, если значение этого элемента чётное.
Комментарии (576)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3506235 Уровень 6
6 ноября 2024
Мой мозг решил это так:

// колво ячеек из 2-х массивов
resultArray = new int[firstArray.length + secondArray.length]; 
        
// копируем значения первого массива
for (int i = 0; i < firstArray.length; i++) { 
    resultArray[i] = firstArray[i];
}

// копируем значения второго массива
for (int j = firstArray.length, z = 0; j < firstArray.length + secondArray.length && z < secondArray.length; j++, z++) {
    resultArray[j] = secondArray[z];
}

for (int i = 0; i < resultArray.length; i++) {
    System.out.print(resultArray[i] + ", ");
}
Anonymous #3508973 Уровень 6
31 октября 2024
Решил задачу в intellij IDEA - компилится и работает прекрасно. Но с сайта - не копирует элементы второго массива в итоговый. IJ IDEA сама ошибки правит что ли?
Alexander Nikitin Уровень 13
20 октября 2024
resultArray = new int[firstArray.length + secondArray.length]; for (int i = 0; i < resultArray.length; i++) { if(i < firstArray.length) { resultArray[i] = firstArray[i]; } else resultArray[i] = secondArray[i-firstArray.length]; System.out.print(resultArray[i] + ", "); }
AlexGarag Уровень 17
27 октября 2024
А если бы не спешил со своей гениальной публикацией, то код мог выглядеть ещё красивее: resultArray = new int[firstArray.length + secondArray.length]; for (int i = 0; i < resultArray.length; i++) { if(i < firstArray.length) resultArray[i] = firstArray[i]; else resultArray[i] = secondArray[i-firstArray.length]; System.out.print(resultArray[i] + ", "); } Но вместо одного for'а С условиями, лучше сделать два for'а БЕЗ условий )))))
Максим Тарасов Уровень 6
15 октября 2024
По сложению массивов Первая мысль - погуглить, легко находятся решения через

System.arraycopy
и

resultArray
однако же, мы этого ещё не проходили, тогда как? Собрал конструкцию на for + if

for (int a = 0; a < resultArray.length; a++)
        {
            if (a < firstArray.length)
            {
                resultArray[a] = firstArray[a];
            } else
// тут кусок кода, не интересно же решение готовое выкладывать. 
            if (a > firstArray.length)
            {
                resultArray[a] = secondArray[a-firstArray.length];
            }
        }
Andrey Уровень 23
10 октября 2024
Хотелось бы привести решение этой на Python 2мя первыми способами пришедшими в голову:

# Python3:

firstArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
secondArray = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

# Solution1:
resultArray = [*firstArray, *secondArray]

# Solution2:
resultArray = firstArray[:]
resultArray.extend(secondArray)


Живите с этим....
Alexander Nikitin Уровень 13
20 октября 2024
и чему ты научишься, если решишь таким способом?
Andrey Уровень 23
21 октября 2024
KISS
CodeMashine Уровень 11
26 октября 2024
из JS

firstArray.concat(secondArrray) ;
resultArray = [...firstArray , ...secondArrray ] ;

но тут java и уверен на 1000% есть метод конкатенации или что то типа spread и тут
Andrey Уровень 23
28 октября 2024
Ну как выяснется неа)) Только Array.copy(), System.arraycopy(),  ИМЯ_КОЛЛЕЦИИ.copy() и все в таком духе. Ну все равно полегче, чем здесь в учебке всех гоняют)))
CodeMashine Уровень 11
29 октября 2024
методы под капотом делают тоже что и нас заставляют. умысел в этом скорее всего. пришла в голову еще одна конструкция из JS которая в Java -дичь

const newArr = [] ;

firstArr.forEach(el=>newArr.push(el)) ;
secondArr.forEach(el=>newArr.push(el)) ;
Ilnar Safiullin Уровень 8
9 октября 2024
очень сложное задание для новичка
Andrey Уровень 23
10 октября 2024
Могу дать алгоритм)) Допустим мы не знаем о существовании метода System.arraycopy()... 1. Проинициализировать переменную resultArray (не в классе, а в методе) суммарной длиной первого и второго массива (firstArray.length + secondArray.length) 2. Плохие новости - мы на JAVA. нам потребуется 2 цикла - первый от нуля до firstArray.length (не включая границу). В нем мы будем записывать результирующий массив по индексу данными по тому же самому индексу из первого массива resultArray[i] = firstArray[i] - второй цикл - ну тут чуть сложнее - он с 0 до secondArray.length. НО! нам же надо заполять элементы резалт массива там где кончились элементы первого (начиная с 10го) ну типа resultArray[i + firstArray.length] = secondArray[i] ну все....
KorbenDallas Уровень 6
5 октября 2024
Не понимаю, зачем все так усложнять. Почему нельзя было написать в статье про System.arraycopy ? Пришлось гуглить и учить отдельно, чтобы решить задачу
CrSimple Уровень 11
17 сентября 2024
По моему у меня самый замороченый код)

    public static void main(String[] args) {
        resultArray = new int[firstArray.length + secondArray.length];
        for(int t = 0; t < firstArray.length; t++) {
            resultArray[t] = firstArray[t];
            for(int a = 0; a < secondArray.length && t == firstArray.length-1; a++) {
                resultArray[firstArray.length+a] = secondArray[a];;
            }
        }
        for (int i = 0; i < resultArray.length; i++) {
            System.out.print(resultArray[i] + ", ");
        }
    }
}
Iakov Lysenko Уровень 13 Expert
12 сентября 2024
Решил задачу через System.arraycopy - валидатор дал добро.
Alexander Elefteriadi Уровень 13
11 сентября 2024
.