Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

1.6. Массивы

Материалы

ТипСсылка
Документссылка
Видеоссылка

Массив - это контейнер, который хранит фиксированное количество значений одного типа. Когда нужно работать с множеством связанных значений, массивы - ваш лучший друг!

Ваш первый массив

Представьте что вам нужно хранить температуры за неделю. Вместо создания семи отдельных переменных, используйте массив:

public class Main {
    public static void main(String[] args) {
        int[] temperatures = {18, 20, 22, 19, 21, 23, 20};
        
        System.out.println("Понедельник: " + temperatures[0] + "°C");
        System.out.println("Вторник: " + temperatures[1] + "°C");
    }
}

Вывод:

Понедельник: 18°C
Вторник: 20°C

Индексация начинается с нуля! Первый элемент имеет индекс 0, второй - 1, и так далее.

Объявление массивов

Есть два способа объявить массив:

// Способ 1 (рекомендуемый)
int[] numbers;
String[] names;

// Способ 2 (не рекомендуется, но работает)
int numbers[];
String names[];

Первый способ более читаемый - квадратные скобки сразу показывают что это массив.

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

Создание массивов

Создание с помощью new

int[] numbers = new int[5];  // массив из 5 целых чисел

Это создаёт массив из 5 элементов, все инициализированы значением по умолчанию (0 для чисел):

[0, 0, 0, 0, 0]

Значения по умолчанию для разных типов:

  • Числа (int, double, и т.д.): 0 или 0.0
  • boolean: false
  • Ссылочные типы: null

Создание с инициализацией

Часто вы знаете значения заранее:

int[] scores = {95, 87, 92, 78, 88};
String[] colors = {"красный", "зелёный", "синий"};

Java автоматически определяет размер массива по количеству элементов.

Работа с элементами

Доступ к элементам

Используйте квадратные скобки и индекс:

int[] numbers = {10, 20, 30, 40, 50};

System.out.println(numbers[0]);  // 10
System.out.println(numbers[2]);  // 30
System.out.println(numbers[4]);  // 50

Изменение элементов

int[] numbers = {10, 20, 30};
numbers[1] = 99;  // изменяем второй элемент

System.out.println(numbers[1]);  // 99

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

Каждый массив знает свою длину:

int[] numbers = {10, 20, 30, 40, 50};
System.out.println("Длина массива: " + numbers.length);  // 5

Важно: length - это свойство, а не метод! Без скобок.

Перебор массивов

С помощью обычного for

int[] numbers = {10, 20, 30, 40, 50};

for (int i = 0; i < numbers.length; i++) {
    System.out.println("Элемент " + i + ": " + numbers[i]);
}

Вывод:

Элемент 0: 10
Элемент 1: 20
Элемент 2: 30
Элемент 3: 40
Элемент 4: 50

С помощью enhanced for (for-each)

Когда индекс не нужен, используйте более простую форму:

int[] numbers = {10, 20, 30, 40, 50};

for (int num : numbers) {
    System.out.println(num);
}

Это читается как “для каждого num в numbers”. Намного проще!

Вычисление суммы

int[] scores = {95, 87, 92, 78, 88};
int sum = 0;

for (int score : scores) {
    sum += score;
}

double average = sum / (double) scores.length;
System.out.println("Средний балл: " + average);

Вывод:

Средний балл: 88.0

Многомерные массивы

Массив может содержать другие массивы! Это полезно для матриц и таблиц.

Двумерный массив (матрица)

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

System.out.println(matrix[0][0]);  // 1
System.out.println(matrix[1][2]);  // 6
System.out.println(matrix[2][1]);  // 8

Визуализация:

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

Создание многомерного массива

// Прямоугольный массив 3x4
int[][] table = new int[3][4];

// "Рваный" массив - строки разной длины
int[][] ragged = {
    {1, 2},
    {3, 4, 5},
    {6}
};

Перебор двумерного массива

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println();  // новая строка
}

Вывод:

1 2 3 
4 5 6 
7 8 9 

С enhanced for:

for (int[] row : matrix) {
    for (int num : row) {
        System.out.print(num + " ");
    }
    System.out.println();
}

Копирование массивов

Почему простое присваивание не работает

int[] original = {1, 2, 3};
int[] copy = original;  // ЭТО НЕ КОПИЯ!

copy[0] = 999;
System.out.println(original[0]);  // 999 - упс!

Переменные массивов хранят ссылки, а не сами данные. Обе переменные указывают на один массив!

Копирование с помощью цикла

int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[original.length];

for (int i = 0; i < original.length; i++) {
    copy[i] = original[i];
}

Работает, но многословно.

Использование System.arraycopy()

int[] original = {1, 2, 3, 4, 5};
int[] copy = new int[original.length];

System.arraycopy(original, 0, copy, 0, original.length);
// System.arraycopy(источник, откуда, назначение, куда, сколько)

Можно копировать часть массива:

String[] coffees = {
    "Affogato", "Americano", "Cappuccino", "Corretto", "Cortado",   
    "Doppio", "Espresso", "Frappucino", "Freddo"
};

String[] selection = new String[4];
System.arraycopy(coffees, 2, selection, 0, 4);

for (String coffee : selection) {
    System.out.print(coffee + " ");
}

Вывод:

Cappuccino Corretto Cortado Doppio 

Использование Arrays.copyOf()

Самый простой способ:

import java.util.Arrays;

int[] original = {1, 2, 3, 4, 5};
int[] copy = Arrays.copyOf(original, original.length);

Можно изменить размер:

int[] bigger = Arrays.copyOf(original, 10);   // новые элементы = 0
int[] smaller = Arrays.copyOf(original, 3);   // только первые 3

Использование Arrays.copyOfRange()

Копирование части массива:

import java.util.Arrays;

String[] coffees = {
    "Affogato", "Americano", "Cappuccino", "Corretto", "Cortado",   
    "Doppio", "Espresso", "Frappucino", "Freddo"
};

String[] selection = Arrays.copyOfRange(coffees, 2, 6);
// От индекса 2 (включительно) до 6 (не включая)

for (String coffee : selection) {
    System.out.print(coffee + " ");
}

Вывод:

Cappuccino Corretto Cortado Doppio 

Полезные методы класса Arrays

Класс java.util.Arrays содержит множество полезных методов для работы с массивами.

Сортировка

import java.util.Arrays;

int[] numbers = {5, 2, 8, 1, 9};
Arrays.sort(numbers);

System.out.println(Arrays.toString(numbers));

Вывод:

[1, 2, 5, 8, 9]

Работает и со строками:

String[] names = {"Зина", "Алиса", "Боб"};
Arrays.sort(names);

System.out.println(Arrays.toString(names));

Вывод:

[Алиса, Боб, Зина]

Бинарный поиск

Быстрый поиск в отсортированном массиве:

import java.util.Arrays;

int[] numbers = {1, 3, 5, 7, 9, 11};
int index = Arrays.binarySearch(numbers, 7);

System.out.println("Число 7 находится на индексе: " + index);  // 3

Важно: Массив должен быть отсортирован! Иначе результат непредсказуем.

Если элемент не найден, возвращается отрицательное число:

int notFound = Arrays.binarySearch(numbers, 4);
System.out.println(notFound);  // -3 (отрицательное)

Заполнение массива

import java.util.Arrays;

int[] numbers = new int[5];
Arrays.fill(numbers, 42);

System.out.println(Arrays.toString(numbers));

Вывод:

[42, 42, 42, 42, 42]

Можно заполнить часть массива:

int[] numbers = new int[10];
Arrays.fill(numbers, 2, 7, 99);  // от индекса 2 до 7

System.out.println(Arrays.toString(numbers));

Вывод:

[0, 0, 99, 99, 99, 99, 99, 0, 0, 0]

Сравнение массивов

import java.util.Arrays;

int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int[] array3 = {1, 2, 4};

System.out.println(Arrays.equals(array1, array2));  // true
System.out.println(Arrays.equals(array1, array3));  // false

Внимание: Оператор == сравнивает ссылки, не содержимое!

System.out.println(array1 == array2);  // false (разные объекты)
System.out.println(Arrays.equals(array1, array2));  // true (одинаковое содержимое)

Преобразование в строку

import java.util.Arrays;

int[] numbers = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(numbers));

Вывод:

[1, 2, 3, 4, 5]

Для многомерных массивов используйте deepToString():

int[][] matrix = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(matrix));

Вывод:

[[1, 2], [3, 4]]

Создание списка из массива

import java.util.Arrays;
import java.util.List;

String[] array = {"Яблоко", "Банан", "Апельсин"};
List<String> list = Arrays.asList(array);

System.out.println(list);

Вывод:

[Яблоко, Банан, Апельсин]

Примечание: Полученный список имеет фиксированный размер - нельзя добавлять или удалять элементы!

Частые ошибки и их решение

ArrayIndexOutOfBoundsException

Самая частая ошибка при работе с массивами:

int[] numbers = {10, 20, 30};
System.out.println(numbers[5]);  // Ошибка! Индекс вне границ

Всегда проверяйте границы:

int index = 5;
if (index >= 0 && index < numbers.length) {
    System.out.println(numbers[index]);
} else {
    System.out.println("Индекс вне границ!");
}

NullPointerException

int[] numbers = null;
System.out.println(numbers.length);  // Ошибка! numbers это null

Проверяйте на null:

if (numbers != null) {
    System.out.println(numbers.length);
} else {
    System.out.println("Массив не инициализирован!");
}

Изменение размера массива

Размер массива фиксирован после создания! Нельзя:

int[] numbers = {1, 2, 3};
numbers.length = 5;  // ОШИБКА КОМПИЛЯЦИИ!

Решение - создать новый массив:

int[] numbers = {1, 2, 3};
int[] bigger = Arrays.copyOf(numbers, 5);

Или используйте ArrayList для динамического размера:

import java.util.ArrayList;

ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);  // можно добавлять сколько угодно!

Практические примеры

Поиск максимального элемента

int[] numbers = {23, 45, 12, 67, 34, 89, 15};
int max = numbers[0];

for (int num : numbers) {
    if (num > max) {
        max = num;
    }
}

System.out.println("Максимум: " + max);  // 89

Реверс массива

int[] numbers = {1, 2, 3, 4, 5};

for (int i = 0; i < numbers.length / 2; i++) {
    int temp = numbers[i];
    numbers[i] = numbers[numbers.length - 1 - i];
    numbers[numbers.length - 1 - i] = temp;
}

System.out.println(Arrays.toString(numbers));

Вывод:

[5, 4, 3, 2, 1]

Удаление дубликатов

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

int[] numbers = {1, 2, 3, 2, 4, 3, 5};

Set<Integer> set = new HashSet<>();
for (int num : numbers) {
    set.add(num);
}

int[] unique = new int[set.size()];
int i = 0;
for (int num : set) {
    unique[i++] = num;
}

Arrays.sort(unique);
System.out.println(Arrays.toString(unique));

Вывод:

[1, 2, 3, 4, 5]

Сдвиг элементов

int[] numbers = {1, 2, 3, 4, 5};

// Сдвиг вправо
int last = numbers[numbers.length - 1];
for (int i = numbers.length - 1; i > 0; i--) {
    numbers[i] = numbers[i - 1];
}
numbers[0] = last;

System.out.println(Arrays.toString(numbers));

Вывод:

[5, 1, 2, 3, 4]

Лучшие практики

Используйте константы для размеров

// Плохо
int[] scores = new int[100];

// Хорошо
final int MAX_STUDENTS = 100;
int[] scores = new int[MAX_STUDENTS];

Проверяйте границы

public static int getElement(int[] array, int index) {
    if (array == null) {
        throw new IllegalArgumentException("Массив null");
    }
    if (index < 0 || index >= array.length) {
        throw new IndexOutOfBoundsException("Индекс: " + index);
    }
    return array[index];
}

Используйте enhanced for когда возможно

// Хорошо для чтения
for (int num : numbers) {
    System.out.println(num);
}

// Используйте обычный for когда нужен индекс
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Индекс " + i + ": " + numbers[i]);
}

Предпочитайте Collections для сложной логики

Для динамических коллекций используйте ArrayList:

// Вместо
int[] numbers = new int[10];
int count = 0;

// Используйте
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(42);  // проще!

Итоги

Вы изучили массивы в Java:

  • Объявление и создание массивов
  • Доступ и изменение элементов
  • Перебор массивов циклами
  • Многомерные массивы
  • Копирование массивов
  • Полезные методы Arrays
  • Частые ошибки и как их избежать
  • Практические примеры

Массивы - фундаментальная структура данных. Они быстрые и эффективные, но помните:

  • Размер фиксирован после создания
  • Индексация начинается с 0
  • Всегда проверяйте границы

Для динамических коллекций рассмотрите использование ArrayList и других классов из пакета java.util.

Задания для практики

Попробуйте написать программы для:

  1. Нахождения второго по величине элемента в массиве
  2. Проверки является ли массив палиндромом
  3. Слияния двух отсортированных массивов в один отсортированный
  4. Подсчёта частоты каждого элемента в массиве

Удачи!