• ,

Java массивы

Массивы


Массив — это структура данных, в которой хранятся величины одинакового типа. Доступ к отдельному элементу массива осуществляется с помощью целого индекса. Например, если а — массив целых чисел, то значение выражения а [ i ] равно i-му целому числу в массиве.

Массив объявляется следующим образом: сначала указывается тип массива, т.е тип элементов, содержащихся в массиве, за которым ставится пара пустых квадратных скобок, а затем — имя переменной. Например, вот как объявляется массив, состоящий из целых чисел:

int[] a;


Однако этот оператор лишь объявляет переменную а, не инициализируя ее настоящим массивом. Чтобы создать массив, нужно применить оператор new.

int[ ] a = new int [100] ;


Этот оператор создает массив, состоящий из 100 целых чисел. Элементы этого массива нумеруются от 0 до 99 (а не от 1 до 100). После создания массив можно заполнять, например, с помощью цикла.

int [ ] а = new int[100];
for (int i = 0; i < 100; i++)
 a[i] = i; // Заполняет массив числами от 0 до 99.


Если вы попытаетесь обратиться к элементу а [100] (или любому другому элементу, индекс которого выходит за пределы диапазона от 0 до 99), создав массив, состоящий из 100 элементов, программа прекратит работу, поскольку возникнет исключительная ситуация, связанная с выходом индекса массива за пределы допустимого диапазона.
Чтобы подсчитать количество элементов в массиве, используйте метод имя Массива.length.

Например,

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


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

Массив можно объявить двумя способами:

int[ ] a; 
или 
int a[ ];


Большинство программистов на языке Java предпочитают первый стиль, поскольку в нем четче отделяется тип массива int [ ] (целочисленный массив) от имени переменной.

Инициализаторы массивов и безымянные массивы


В языке Java есть средство для одновременного создания массива и его инициализации. Вот пример такой синтаксической конструкции:

int[] smallPrimes = { 2, 3, 5, 7, 11, 13};


Отметим, что в этом случае не нужно применять оператор new. Кроме того, можно даже инициализировать безымянный массив:

new int [ ] { 16, 19, 23 , 29 , 31, 37}


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

smallPrimes = new int{ 17, 19, 23, 29, 31, 37 };


представляет собой укороченную запись выражения

int[] anonymous = { 17, 19, 23, 29, 31, 37 };
smailPrimes = anonymous;


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

new тип Элементов[]


Заметим, что такой массив не эквивалентен объекту null.

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


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

int[] luckyNumbers = smailPrimes;
luckyNuimbers[5] = 12; // Теперь элемент smailPrimes[5]также равен 12.


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

System.arraycopy(from, fromlndex, to, tolndex, count);


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

Рис.3.1. Копирование массива


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

int[] smailPrimes = {2, 3, 5, 7, 11, 13};
int[] luckyNumbers = {1001, 1002, 1003, 1004, 1005, 1006, 1007};
System.аггаусору(smailPrimes, 2, luckyNumbers, 3, 4);
for (int i = 0; i < luckyNumbers.length; i++)
System.println(i +.": " + luckyNumbersfi]);


Выполнение этих операторов приводит к следующему результату.

0: 1001
1: 1002
2: 1003
3: 5
4: 7
5: 11
6: 13


Рис. 3.2. Копирование элементов массива


Массив в языке Java значительно отличается от массива в языке C++. Однако он практически совпадает с указателем на динамический массив. Это значит, что оператор

int[] a = new int[100]; //Java


эквивалентен оператору

i n t * = new i n t [ 1 0 0 ] ; // C++,
а не
int a[100]; // C++


В языке Java оператор [ ] no умолчанию проверяет диапазон изменения индексов. Кроме того, в языке Java нет арифметики указателей — нельзя увеличить указатель а, чтобы обратиться к следующему элементу массива.

Ссылка на первоисточник: www.java-study.ru/java-uchebnik/88-java-massivy

15 комментариев

zibul444
аггаусору — какие данные на каких местах за что отвечают… если с первыми можно догадаться(из примера), то с последним — как-то не вышло…
d-makarov
  • d-makarov
  • +1
  • Комментарий отредактирован 2016-01-14 21:24:36 пользователем d-makarov
System.arraycopy(from, fromlndex, to, tolndex, count)

from — исходный массив.
fromIndex — индекс элемента, с которого в исходном массиве начинается копирование.
to — массив, в который копируются элементы исходного массива.
toIndex — индекс элемента, с которого в массив to начнется вставка.
count — количество элементов, которые требуется скопировать.
Например:
System.аггаусору(smailPrimes, 2, luckyNumbers, 3, 4)

Из массива smailPrimes, начиная с третьего (индекс 2) элемента, вставить четыре элемента в массив luckyNumbers, начиная с четвертого (индекс 3) элемента.
zibul444
Благодарю!
Norg
  • Norg
  • +1
  • Комментарий отредактирован 2016-02-04 12:54:14 пользователем Norg
Чтобы подсчитать количество элементов в массиве, используйте метод имя Массива.length.
length — не метод, а поле. За остальной материал спасибо, полезно.
MaxST1994
Кхм кхм, не стоит путать новичков.

Стоит объяснить что есть
length — поле. Оно есть у массивов, то бишь чтобы получить длину массива пишем

int [] a = new int [3]; 
return(a.length);


и есть
length() — метод. Метод класса строк. и если мы захотим вернуть длину строки — пишем:
String str = "qwerty"; 
return (str.length());


А почему и менно так? Да все очень просто. Массивы это почти как примитивные типы, но не совсем они, главное — это не класс. Массивы не относятся к коллекциям/спискам. Поэтому у них поле. Строка же (String) — класс, и у него есть метод length(), который мы и используем.

Я понял так. Если не прав — исправьте.
Norg
  • Norg
  • 0
  • Комментарий отредактирован 2016-03-11 12:23:01 пользователем Norg
Чтобы подсчитать количество элементов в массиве, используйте метод имя Массива.length
Речь не о строке, речь — о массиве. И у метода должны быть скобки, верно?
Массив — объект, у него есть поле length, и (смотрим на исходную цитату в первой строке этого поста) чтобы подсчитать количество элементов в массиве, надо использовать поле length.

Теперь к вам большая просьба не путать новичков:
Массивы это почти как примитивные типы, но не совсем они, главное — это не класс. Массивы не относятся к коллекциям/спискам. Поэтому у них поле.
Скажите, а какие поля есть у int? А у double? У примитивных типов нет никаких полей. Поля есть только у классов, и массив — как раз и есть класс. Именно поэтому у него поле. А есть и методы, в частности, наследуемые от класса Object: clone(), toString() и другие.
Joysi
Конкретно по lenght вопрос не такой простой, как кажется!

Каждый объект в JVM физически размещается в памяти следующим образом:
1) Заголовок объекта
2) Память для примитивных типов
3) Память для ссылочных типов
4) Смещение/выравнивание (к машинному слову 32 или 64 бита)

Заголовок в свою очередь, обычно:
Занимает 8 байт для 32bit, 16байт для 64bit JDK.
Первую половину заголовка (Mark Word) занимает:
1)Hash Code — Object.hashCode() вернет адрес объекта в памяти.
2)GCI (Garbage Collection Information) — каждый java объект содержит информацию нужную для системы управления памятью.
3)Lock — каждый объект содержит информацию о состоянии блокировки. Это может быть указатель на объект блокировки или прямое представление блокировки.
Вторую половину заголовка занимает Type Information Block Pointer который содержит указатель на структуру о типе объекта (таблица виртуальных методов + доп указатели)
И, внимание(!), только для объектов типа array (и никаких других) Array Length — 4 байта для хранения длины массива.

То есть это не совсем свойство объекта в классическом понимании. Оно «обернуто» как свойство.
И точно уж не метод!

Также необходимо подчеркнуть(чего в статье нет) что в Java нет многомерных массивов в смысле например языков типа Pascal.
Совсем нет!
Объявляя int[][] a; мы будем иметь место не с классической матрицей, а с
массивом массивов. Причем можем сделать так что в каждая «строка» такой «матрицы» будет содержать
разное количество элементов.

Не зная этого можно попасть на примерно такой зихер:
1) В чем разница между эквивалентными с точки зрения хранилища для 2М байт объявлениями
byte[][] a=new byte[2][1000000]
и
byte[][] a=new byte[1000000][2]
?
В том, что в первом случае будет кушать в 14 раз меньше памяти (для 64бит JDK)!
Разницу в памяти кушают дополнительные почти миллион заголовков.
Поэксперементируйте:

public static void main(String[] args) {
  long memStart = Runtime.getRuntime().freeMemory();
  byte[][]  a = byte int[2][1000000];
  //byte[][]  a = byte int[1000000][2];
  long memEnd = Runtime.getRuntime().freeMemory();
  System.out.println("Memory used=" + ((memStart-memEnd)>>10) + " Кbytes");
}
MaxST1994
Ха, а какой добрый человек решил что может заминусовать меня? :) Если бы не мой коммент ни у кого бы и в голову не пришло разжевать length так что «пожалуйста»
Joysi
Пострадали за правое дело :)
Вообще не всегда простые вещи являются таки по сути.
tanzwud
Да памяти будет использовано в первом случае в ~10 Раз меньше. Однако эти «хранилища отнюдь не эквиваленты».
1. В джаве нету многомерных массивов, только массивы массивов, как замечено, не знаю что такое заголовки, однако разница в памяти может быть как раз из-за разници в количестве обьектов созданных. 2 против 1000000 как вариант.
2. byte[][] a=new byte[2][1000000] -> Предстваляет собой 2 обьекта, каждый из которых массив на 1000000 примитивов когда в случаше с byte[][] a=new byte[1000000][2] это 1000000 обьектов каждый из которых массив на 2 примитива.
3. Т.к. массивы это обьекты, в Java не совсем просто взять и на шару рассчитать размер обьекта.
4. Не всегда ясно как работает JVM поэтому считать памятиь до и после не думаю что верно. Как вариант можно серелизовать обьект и записать в файл. Проверить итоговый размер. Однако там будет зависимость размера от протокола.
Akula
Понравилось. Спасибо за инфу о подсчёте памяти!
Akula
Вообщето-то в Java все элементы, кроме примитивов — объекты. А разница между полем length и методом length() лежит лишь в фантазии создателей языка. Сомневаюсь, что были какие-то существенные проблемы в создании поля для класса String под названием length. Просто так получилось. Фича типа.
Vasekspbgmtu
System.println(i +.": " + luckyNumbersfi]); — опечатка полагаю
maximuswork
Ошибка!
for (int i = 0; i < a. length; i++ System.out.println (a[i]);
не хватает ")" должно быть: for (int i = 0; i < a. length; i++) System.out.println (a[i]);
snuk
  • snuk
  • 0
  • Комментарий отредактирован 2017-10-19 07:18:09 пользователем snuk
Да, ошибка, но не стоит там вставлять скобку, как хочет компилятор. Он лишь первый разумный вариант предлагает. Но код от этого становится плохо усваиваемым. Лучше поставить запятую после инкремента и закрыть все скобкой, т.е.
for (int i = 0; i < a. length; i++, System.out.println (a[i]));
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.