Рубрики
Без рубрики

Операции с массивом на Java

Узнайте, как мы можем обрабатывать операции общего массива на Java.

Автор оригинала: Ger Roza.

1. Обзор

Любой java-разработчик знает, что создание чистого и эффективного решения при работе с операциями массива не всегда легко достичь. Тем не менее, они являются центральной частью экосистемы Java – и нам придется иметь дело с ними несколько раз.

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

2. Классы массивов и помощников

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

Обратите внимание, что основные операции, которые поддерживает массив, в определенном смысле ограничены. Это не редкость, чтобы увидеть сложные алгоритмы для выполнения относительно простых задач, когда дело доходит до массивов.

По этой причине, для большинства наших операций, мы будем использовать помощник классов и методов, чтобы помочь нам: Массивы класс, предоставляемый Java и Apache ArrayUtils Один.

Чтобы включить последнее в наш проект, мы должны добавить Апач Викисклад зависимость:


    org.apache.commons
    commons-lang3
    3.11

Мы можем проверить последнюю версию этого артефакта на Мавен Центральной .

3. Получить первый и последний элемент массива

Это одна из наиболее распространенных и простых задач благодаря индексу доступа к массивам.

Начнем с объявления и инициализации int массив, который будет использоваться во всех наших примерах (если мы не указать иное):

int[] array = new int[] { 3, 5, 2, 5, 14, 4 };

Зная, что первый элемент массива связан с значением индекса 0 и что он имеет длина атрибут, который мы можем использовать, то это просто, чтобы выяснить, как мы можем получить эти два элемента:

int firstItem = array[0];
int lastItem = array[array.length - 1];

4. Получить случайное значение от массива

Используя java.util.Random объект, который мы можем легко получить любую ценность от нашего массива:

int anyValue = array[new Random().nextInt(array.length)];

5. Приложение нового элемента к массиву

Как известно, массивы имеют фиксированный размер значений. Таким образом, мы не можем просто добавить элемент и превысить этот предел.

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

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

int[] newArray = Arrays.copyOf(array, array.length + 1);
newArray[newArray.length - 1] = newItem;

По желанию, если ArrayUtils класс доступен в нашем проекте, мы можем использовать его добавить метод (или его addAll альтернатива) для достижения нашей цели в одной строке заявление:

int[] newArray = ArrayUtils.add(array, newItem);

Как мы можем себе представить, этот метод не изменяет исходный массив объект; мы должны присвоить его выход новой переменной.

6. Вставьте значение между двумя значениями

Из-за своего индекса значения символа, вставка элемента в массиве между двумя другими не является тривиальной работой.

Apache счел это типичным сценарием и внедрил метод в своей ArrayUtils класс для упрощения решения:

int[] largerArray = ArrayUtils.insert(2, array, 77);

Мы должны указать индекс, в который мы хотим вставить значение, и выход будет новый массив, содержащий большее количество элементов.

Последним аргументом является переменный аргумент (он же vararg ), таким образом, мы можем вставить любое количество элементов в массиве.

7. Сравните два массива

Несмотря на то, что массивы Объект s и, следовательно, обеспечить равняется метод, они используют реализацию по умолчанию его, опираясь только на равенство ссылок.

Мы можем так или иначе вызвать java.util.Arraysравняется метод проверки того, содержат ли два объекта массива одинаковые значения:

boolean areEqual = Arrays.equals(array1, array2);

Примечание: этот метод не эффективен для зубчатые массивы . Соответствующим методом проверки равенства многомерных структур является Arrays.deepEquals Один.

8. Проверьте, пуст ли массив

Это несложное задание, имея в виду, что мы можем использовать длина атрибут массивов:

boolean isEmpty = array == null || array.length == 0;

Кроме того, у нас также есть нулевой безопасный метод в ArrayUtils класс помощников, которые мы можем использовать:

boolean isEmpty = ArrayUtils.isEmpty(array);

Эта функция по-прежнему зависит от длины структуры данных, которая считает недействительными и пустыми под массивы как действительные значения тоже, так что нам придется следить за этими случаями края:

// These are empty arrays
Integer[] array1 = {};
Integer[] array2 = null;
Integer[] array3 = new Integer[0];

// All these will NOT be considered empty
Integer[] array3 = { null, null, null };
Integer[][] array4 = { {}, {}, {} };
Integer[] array5 = new Integer[3];

9. Как перемешать элементы массива

Для того, чтобы перетасовать элементы в массиве, мы можем использовать ArrayUtil ‘S особенность:

ArrayUtils.shuffle(array);

Это пустота метод и работает на фактических значениях массива.

10. Массивы коробки и распаковки

Мы часто сталкиваемся с методами, которые поддерживают только Объект на основе массивов.

Снова ArrayUtils класс помощников пригодится, чтобы получить коробочную версию нашего примитивного массива:

Integer[] list = ArrayUtils.toObject(array);

Возможна и обратная операция:

Integer[] objectArray = { 3, 5, 2, 5, 14, 4 };
int[] array = ArrayUtils.toPrimitive(objectArray);

11. Удалите дубликаты из массива

Самый простой способ удаления дубликатов – это преобразование массива в набор реализация.

Как мы знаем, Коллекционая s использовать Generics и, следовательно, не поддерживают примитивные типы.

По этой причине, если мы не обуасвим массивы на основе объектов, как в нашем примере, нам сначала нужно будет обработать наши значения:

// Box
Integer[] list = ArrayUtils.toObject(array);
// Remove duplicates
Set set = new HashSet(Arrays.asList(list));
// Create array and unbox
return ArrayUtils.toPrimitive(set.toArray(new Integer[set.size()]));

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

Кроме того, если нам необходимо сохранить порядок наших элементов, мы должны использовать другую Установить реализации, например, LinkedHashSet .

12. Как распечатать массив

То же, что и с равняется метод, набор массива toString функция использует реализацию по умолчанию, предоставляемую Объект класс, который не очень полезен.

Оба Массивы и ArrayUtils классы отправки с их реализации для преобразования структур данных в читаемый Струнные .

Помимо несколько иного формата, который они используют, наиболее важным отличием является то, как они относятся к многомерным объектам.

Класс Java Util предоставляет два статических метода, которые мы можем использовать:

  • toString : не работает хорошо с зубчатыми массивами
  • deepToString : поддерживает любую Объект на основе массивов, но не компилирует с примитивными аргументами массива

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

String arrayAsString = ArrayUtils.toString(array);

13. Карта массива к другому типу

Часто полезно применять операции на всех элементов массива, возможно, превращая их в другой тип объекта.

С этой целью, Мы постараемся создать гибкий метод помощников с использованием Generics:

public static  U[] mapObjectArray(
  T[] array, Function function,
  Class targetClazz) {
    U[] newArray = (U[]) Array.newInstance(targetClazz, array.length);
    for (int i = 0; i < array.length; i++) {
        newArray[i] = function.apply(array[i]);
    }
    return newArray;
}

Если мы не используем Java 8 в нашем проекте, мы можем отказаться от Функциональные аргумент, и создать метод для каждого отображения, что мы должны выполнить.

Теперь мы можем повторно использовать наш общий метод для различных операций. Давайте создадим два тестовых случая, чтобы проиллюстрировать это:

@Test
public void whenMapArrayMultiplyingValues_thenReturnMultipliedArray() {
    Integer[] multipliedExpectedArray = new Integer[] { 6, 10, 4, 10, 28, 8 };
    Integer[] output = 
      MyHelperClass.mapObjectArray(array, value -> value * 2, Integer.class);

    assertThat(output).containsExactly(multipliedExpectedArray);
}

@Test
public void whenMapDividingObjectArray_thenReturnMultipliedArray() {
    Double[] multipliedExpectedArray = new Double[] { 1.5, 2.5, 1.0, 2.5, 7.0, 2.0 };
    Double[] output =
      MyHelperClass.mapObjectArray(array, value -> value / 2.0, Double.class);

    assertThat(output).containsExactly(multipliedExpectedArray);
}

Для примитивных типов, мы должны боксировать наши значения в первую очередь.

В качестве альтернативы мы можем обратиться к Потоки Java 8 для выполнения отображения для нас.

Нам нужно превратить массив в Поток Объект s в первую очередь. Мы можем сделать это с Arrays.stream метод.

Например, если мы хотим составить карту наших int значения пользовательского Струнные представительство, мы будем осуществлять это:

String[] stringArray = Arrays.stream(array)
  .mapToObj(value -> String.format("Value: %s", value))
  .toArray(String[]::new);

14. Значения фильтра в массиве

Фильтрация значений из коллекции является общей задачей, которую нам, возможно, придется выполнять более чем в одном случае.

Это потому, что в то время как мы создаем массив, который будет получать значения, мы не можем быть уверены в его окончательный размер. Поэтому Мы будем полагаться на Поток s подход снова.

Представьте, что мы хотим удалить все нечетные числа из массива:

int[] evenArray = Arrays.stream(array)
  .filter(value -> value % 2 == 0)
  .toArray();

15. Другие операции общего массива

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

Помимо тех, которые показаны в этом учебнике, мы широко рассмотрели другие операции в посвященных должностей:

  • Проверьте, содержит ли Java Array значение
  • Как скопировать массив на Java
  • Удаление первого элемента массива
  • Поиск Мина и Макса в массиве с Java
  • Найти Sum и Average в Java Array
  • Как инвертировать массив в Java
  • Присоединиться и разделить массивы и коллекции на Java
  • Объединение различных типов коллекций на Java
  • Найти все пары чисел в массиве, который добавляет до данной суммы
  • Сортировка на Java
  • Эффективный калькулятор частоты слов в Java
  • Сортировка вставки в Java

16. Заключение

Arrays являются одной из основных функций Java, и поэтому очень важно понять, как они работают, и знать, что мы можем и не можем с ними сделать.

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

Как всегда, полный исходный код рабочих примеров доступен на наш Github репо .