Массивы в Java

      Комментарии к записи Массивы в Java отключены

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 4 нед. назад.

  • Автор
    Сообщения
  • #3522
    Предыдущий урок Содержание Следующий урок

    Массив – это набор однотипных переменных, на которые ссылаются по общему имени. Массивы можно создавать из элементов любого типа, и они могут иметь одно или несколько измерений. К определенному элементу в массиве обращаются по его индексу (номеру). В заметке мы рассмотрим обработку одномерных и двумерных массивов.

    Одномерные массивы в Java

    Одномерный массив – это, по существу, список однотипных переменных. Чтобы создать массив, сначала следует создать переменную массива (array variable) желательного типа. Общий формат объявления одномерного массива:
    type var-name [ ] ;
    Здесь type объявляет базовый тип массива; var-name – имя переменной массива. Базовый тип определяет тип данных каждого элемента массива. Например, объявление одномерного массива int-компонентов с именем month_days имеет вид:
    int month_days [];
    Хотя это объявление и устанавливает факт, что month_days является переменной массива, никакой массив в действительности не существует. Фактически, значение month_days установлено в null (пустой указатель), который представляет массив без значения. Чтобы связать month_days с факти­ческим, физическим массивом целых чисел, нужно выделить память для него, используя операцию new, и назначать ее массиву month_days; new – это специальная операция, которая распределяет память.

    Общий формат new в применении к одномерным массивам имеет вид:
    array-var = new type [size] ;
    где type – тип распределяемых данных, [java]size – число элементов в массиве, array-var– переменная, которая[/java] связана с массивом. Чтобы использовать new для распределения памяти под массив, нужно специфицировать тип и число элементов массива. Элементы в массиве, выделенные операцией new, будут автоматически инициализированы нулями. Следующий пример распределяет память для 12-элементного массива целых чисел и связывает его с переменной month_days.
    month_days = new int[12];
    После того как эта инструкция выполнится, month_days будет ссылаться на массив из двенадцати целых чисел. Затем все элементы в массиве будут инициализированы нулями.
    Процесс получения массива включает два шага. Во-первых, следует объявить переменную массива желательного типа. Во-вторых, необходимо выделить память, которая будет содержать массив, используя операцию new, и назначать ее переменной массива. Таким образом, в Java все массивы явля­ются динамически распределяемыми.

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

    Возможна комбинация объявления переменной типа массив с выделением массиву памяти непосредственно в объявлении:
    int month_days[] = new int[12];

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

    public class FindReplace {
      public static void main(String[] args) {
        int myArray[]; // объявление без инициализации
        int mySecond[] = new int[100]; /* выделение памяти
          с инициализацией значениями по умолчанию */
        int a[] = {5, 10, 0, -5, 16, -2}; // объявление с инициализацией
        int max = a[0];
        for (int i = 0; i < a.length; i++) {
          if (a[i]<0)
            a[i] = max;
          mySecond[i] = a[i];
          System.out.println("a[" + i + "]=" + a[i]);
        }
        myArray = a; // установка ссылки на массив a
      }
    }

    В результате выполнения будет выведено:

    >java FindReplace 
    a[0]=5
    a[1]=10
    a[2]=0
    a[3]=5
    a[4]=16
    a[5]=5

    Присваивание mySecond[i] = a[i] приведет к тому, что части элементов массива mySecond, а именно шести, будут присвоены значения элементов массива a. Остальные элементы mySecond сохранят значения, полученные при инициализации, то есть нули. Если же присваивание организовать в виде mySecond = a или myArray = a, то оба массива участвующие в присваивании получат ссылку на массив a, то есть оба будут содержать по шесть элементов и ссылаться на один и тот же участок памяти.
    Массивы можно инициализировать во время их объявления. Процесс во многом аналогичен тому, что используется при инициализации простых ти­пов. Инициализатор массива – это список разделенных запятыми выражений, окруженный фигурными скобками. Массив будет автоматически создаваться достаточно большим, чтобы содержать столько элементов, сколько вы определяете в инициализаторе массива. Нет необходимости использовать операцию new. Например, чтобы хранить число дней в каждом месяце, сле­дующий код создает инициализированный массив целых чисел:

    public class MonthDays {
      public static void main(String[] args) {
        int month_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        System.out.println("Апрель содержит " + month_days[3] + " дней.");
      }
    }

    В результате выполнения программы на экран будет выведено:

    Апрель содержит 30 дней.

    Замечание: Java делает строгие проверки, чтобы удостовериться, что вы случайно не пробуете сохранять или читать значения вне области хранения массива. Исполнительная система Java тоже делает тщательные проверки, чтобы убедиться, что все индексы массивов находятся в правильном диапазоне. (В этом отношении Java существенно отличается от языков C/C++, которые не обеспечивают проверки границ во время выполнения).

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

    В Java многомерные массивы – это, фактически, массивы массивов. Они выглядят и действуют подобно регулярным многомерным массивам. Однако имеется пара тонких различий. Чтобы объявить многомерную переменную массива, определите каждый дополнительный индекс, используя другой набор квадратных скобок. Например, следующее утверждение объявляет переменную двумерного массива с именем twoD:
    int twoD[][] = new int[4][5];
    Оно распределяет память для массива 4x5 и назначает ее переменной twoD. Внутренне эта матрица реализована как массив массивов целых чисел тип int.
    Многомерные массивы возможно инициализировать. Для этого просто включают инициализатор каждого измерения в его собственный набор фи­гурных скобок.
    В следующей программе создаются и инициализируются массивы массивов равной длины (матрицы), и выполняется произведение одной матрицы на другую:

    public class Matrix {
      private int [][] a;
      Matrix(int n, int m) {
        // создание и заполнение с random
        a = new int[n][m];
        for (int i = 0; i < n; ++i)
          for (int j = 0; j < m; ++j)
            a[i][j] = (int) (Math.random()*5);
        show();
      }
      
      public Matrix(int n, int m, int k) {
        // создание и заполнение с random
        a = new int[n][m];
        for (int i = 0; i < n; ++i)
          for (int j = 0; j < m; ++j)
            a[i][j] = k;
        if (k != 0)
          show();
      }
      
      public void show() {
        System.out.println("Матрица:" + a.length + " на " + a[0].length);
        for (int i = 0; i < a.length; ++i) {
          for (int j = 0; j < a[0].length; ++j)
            System.out.print(a[i][j] + " ");
          System.out.println();
        }
      }
            
      public static void main(String[] args) {
        int n = 2, m = 3, z = 4;
        Matrix p = new Matrix(n, m);
        Matrix q = new Matrix(m, z);
        Matrix r = new Matrix(n, z, 0);
        
        for (int i = 0; i < p.a.length; ++i) 
          for (int j = 0; j < q.a[0].length; ++j) 
            for (int k = 0; k < p.a[i].length; ++k) 
              r.a[i][j] += p.a[i][k]*q.a[k][j];
              
        
        System.out.println("Произведение матриц: ");
        r.show();
      }
    }

    Так как значения элементам массивов присваиваются при помощи метода random(), то одним и вариантов выполнения кода может быть следующий:

    > javac Matrix.java
    > java Matrix 
    Матрица:2 на 3
    3 2 0 
    3 3 1 
    Матрица:3 на 4
    1 2 2 3 
    3 2 3 2 
    1 2 3 2 
    Произведение матриц: 
    Матрица:2 на 4
    9 10 12 13 
    13 14 18 17 

    Следующий пример демонстрирует копирование массива:

    public class ArrayCopyDemo {
      public static void main(String[] args) {
        int mas1[] = {1,2,3}, mas2[] = {4,5,6,7,8,9};
        
        System.out.print("mas1[]: ");
        show(mas1);
        
        System.out.print("mas2[]: ");
        show(mas2);
        
        // копирование массива mas1 в mas2
        System.arraycopy(mas1, 0, mas2, 2, 3);
        /*  0 - mas1 копируется начиная с нулевого элемента
         *  2 - элемент, с которого начинается замена
         *  3 - количество копируемых элементов
        */
        
        System.out.println("\n после arraycopy(): ");
        System.out.print("mas1: ");
        show(mas1);
        System.out.print("\nmas2: ");
        show(mas2);
      }
      
      private static void show(int[] mas) {
        for (int i = 0; i < mas.length; ++i)
          System.out.print(" " + mas[i]);
      }
    }

    Результат выполнения программы:

    > javac ArrayCopyDemo.java 
    > java ArrayCopyDemo 
    mas1[]:  1 2 3mas2[]:  4 5 6 7 8 9
     после arraycopy(): 
    mas1:  1 2 3
    mas2:  4 5 1 2 3 9

    Альтернативный синтаксис объявления массива

    Существует иная форма, которая может использоваться для объявления массива:
    type [ ] var-name;
    Здесь квадратные скобки следуют за спецификатором типа, а не именем переменной массива. Например, следующие два объявления эквивалентны:

    int al[] = new int[3];
    int[]  a2 = new int[3];

    Представленные здесь объявления также эквивалентны:
    char twodi[][] = new char[3][4];
    char[][]  twod2 = new char[3][4];

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

Для ответа в этой теме необходимо авторизоваться.