Многомерные массивы в Java. Как преобразовать массив в ассоциативный?

Массивы в Java используются довольно часто. В этой статье мы поговорим про многомерные (двумерные, трёхмерные) и ассоциативные массивы. И, разумеется, приведём соответствующие примеры.

В первую очередь, рассмотрим пример объявления многомерного массива:

int[][] a = new int[3][4];

Итак, перед нами 2-мерный Java-массив, который может включать в себя до 12 элементов типа int:

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

Таким же образом объявляется и 3-мерный (3D) массив:

String[][][] personalInfo = new String[3][4][2];

Здесь перед нами 3-мерный массив, который может содержать до 24 (3 x 4 x 2) элементов типа String.

Составляющие многомерного массива в Java тоже являются массивами. При этом, в отличие от C/C++, ряды массивов в Java могут быть разной длины.

Инициализируем двухмерный массив в Java

Давайте посмотрим, как инициализируется многомерный (в нашем случае — двумерный) Java-массив:

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

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

Докажем это с помощью кода:

class Two2DArray {
   public static void main(String[] args) {

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

      System.out.println("Длина ряда № 1: " + a[0].length);
      System.out.println("Длина ряда № 2: " + a[1].length);
      System.out.println("Длина ряда № 3: " + a[2].length);
   }
}

Результат будет следующим

Длина ряда 1: 3
Длина ряда 2: 4
Длина ряда 3: 1

Т. к. многомерный массив включает в себя отдельные массивы (a[0], a[1] и a[2]), мы можем задействовать метод length, чтобы определить длину каждого ряда 2-мерного Java-массива.

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

class TwoDArray {
   public static void main(String[] args) {

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

     for (int i = 0; i < a.length; ++i) {
        for(int j = 0; j < a[i].length; ++j) {
           System.out.println(a[i][j]);
        }
     }
   }
}

Когда надо пройтись по элементам массива, использование цикла for…each — одно из лучших решений. Пример сортировки двухмерного Java-массива мы можем записать посредством цикла for…each таким образом:

class TwoDArray {
   public static void main(String[] args) {

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

     for (int[] innerArray: a) {
        for(int data: innerArray) {
           System.out.println(data);
        }
     }
   }
}

Запустив этот код, мы увидим итог заполнения двумерного Java-массива:

1
-2
3
-4
-5
6
9
7

Инициализируем 3-мерный массив в Java

На самом деле, трёхмерный массив инициализируется практически так же, как и двумерный:

// test — 3-мерный массив
int[][][] test = {
              {
               {1, -2, 3}, 
               {2, 3, 4}
              }, 
              { 
               {-4, -5, 6, 9}, 
               {1}, 
               {2, 3}
              } 
};

Трёхмерный Java-массив состоит из 2-мерных массивов. И, разумеется, длина рядов может быть различна.

Давайте напишем программу, выводящую элементы 3-мерного массива посредством циклов:

class ThreeDArray {
   public static void main(String[] args) {

     // test – 3-мерный массив
     int[][][] test = {
              {
               {1, -2, 3}, 
               {2, 3, 4}
              }, 
              { 
               {-4, -5, 6, 9}, 
               {1}, 
               {2, 3}
              } 
     };

     // цикл for..each проходит по всем элементам 3-мерного массива
     for (int[][] array2D: test) {
        for (int[] array1D: array2D) {
           for(int item: array1D) {
              System.out.println(item);
           }
        }
     }
  }
}

Итог будет следующим:

1
-2
3
2
3
4
-4
-5
6
9
1
2
3

Ассоциативные массивы в Java

У ассоциативного массива в качестве ключей применяются строки. Мы можем представить его структуру данных в виде совокупности пары «ключ-значение». В таком массиве, как ассоциативный, любое значение связано с конкретным ключом, а доступ к значению производится по имени ключа.

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

Однако есть способ реализовать похожую структуру данных, используя стандартные средства Java SE. В частности, мы можем создать простейший ассоциативный массив, воспользовавшись классом HashMap и установив для его экземпляра строковый тип данных ключа.

Посмотрим, как это работает:

    HashMap<String, Integer> fruits = new HashMap();
fruits.put("Число апельсинов", 5);
fruits.put("Число яблок", 10);
fruits.put("Число мандаринов", 7);
System.out.println(fruits.get("Число мандаринов"));

Мы можем создать ассоциативный массив и с более сложной структурой, поместив объекты HashMap друг в друга и получив тем самым «ассоциативные массивы в ассоциативном массиве». Посмотрим, как это выглядит на практике:

    HashMap<String, Integer> fruits = new HashMap();
fruits.put("Число апельсинов", 5);
fruits.put("Число яблок", 10);
fruits.put("Число мандаринов", 7);
HashMap<String, Integer> milkProducts = new HashMap();
milkProducts.put("Число пачек творога", 2);
milkProducts.put("Число пакетов молока", 3);
milkProducts.put("Число банок сметаны", 17);
HashMap<String, HashMap<String, Integer> > eat = new HashMap();
eat.put("Фрукты", fruits);
eat.put("Молочные продукты", milkProducts);
System.out.println(eat.get("Молочные продукты").get("Число пакетов молока"));

В результате мы решим проблему отсутствия ассоциативных массивов в Java.

При подготовке статьи использовались следующие материалы: — Java Multidimensional Arrays; — «Ассоциативные массивы в Java».