5 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Популярные методы для работы с Java массивами

Pro Java

Страницы

19 мая 2015 г.

Массивы. Часть 4 – практика работы с массивами.

Теперь еще немного попрактикуемся с массивами, рассмотрим некоторые методы из стандартных библиотек JDK, а так же обсудим некоторые моменты, которые остались за рамками предыдущих постов.

В стандартной библиотеке JDK существует класс java.util.Arrays содержащий методы для работы с массивами. Мы тут рассмотрим конечно далеко не все, а лишь некоторые, но ссылка у вас уже есть, так что все остальное можете изучить сами.

Сперва еще раз затронем тему ссылок. Разберем простой пример сравнения двух массивов:

int [] a = < 1 , 2 >;
int [] b = < 1 , 2 >;
println ( “a==b is ” + ( a == b )) ; // сравнивает ссылки
println ( “a.equals(b) is ” + a . equals ( b )) ; // сравнивает ссылки

Хотя содержимое массивов a и b равно, но если мы просто сравним a==b, то результатом будет false, поскольку в данном случае произойдет сравнение ссылок, которые будут разными, так как указывают на разные объекты. Метод equals существует для многих классов Java и как правило он сравнивает содержимое этих объектов, но для массивов он почему-то тоже сравнивает ссылки.

Для сравнения одномерных массивов существует метод Arrays.equals, который сравнивает содержимое массивов. Для сравнения многомерных массивов есть метод Arrays.deepEquals.

Arrays . equals ( a , b )

в результате сравнения массивов а и b выдаст true.

Для копирования одномерного массива есть метод Arrays.copyOf, к сожалению, для многомерных массивов такого метода нет. По существу, если посмотреть код данного метода, он использует системный метод java.lang.System.arraycopy, который кстати сказать, работает очень быстро, но к сожалению тоже применим только для одномерных массивов.

С методом Arrays.copyOf мы уже сталкивались, когда рассматривали программу сортировки одномерного массива Array03.java. Методы Arrays.toString и Arrays.deepToString преобразуют одномерные и многомерные массивы соответственно в строку, более менее удобную для вывода на консоль. С ними мы уже сталкивались в предыдущем посте.

Метода Arrays.sort сортирует одномерный массив, метода для сортировки многомерных массивов в стандартной библиотеке Java нет.

Метод Arrays.binarySearch ищет в одномерном массиве заданное значение и возвращает его индекс.

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

Теперь немножко практики чтобы закрепить все вышесказанное:

Данная программа может сгенерировать следующий вывод:

Тут все просто, поэтому идем сразу дальше к методу java.lang.System.arraycopy. Он очень интересен, так как работает очень быстро, быстрее чем копирование при помощи цикла for. Рассмотрим программу копирования массива состоящего из 10 миллионов значений int, каждый элемент массива содержит значение типа int равное индексу данного элемента. Даже на заполнение данного массива значениями требуется некоторое время. Далее происходит сортировка циклом for и методом java.lang.System.arraycopy. И выводится время затраченное в обоих методах. Как говорится почувствуйте разницу.

Данная программа может сгенерировать такой вывод (зависит от мощности вашего компьютера):

При запуске этой программы, может показаться, что она немного подзависла. Но терпение господа! Заполнить массив 10 миллионами значений и потом их еще два раза скопировать – это занимает время.

Еще стоит упомянуть о возможности передавать массивы в методы. Хоть пока мы методы и не рассматривали, так как не рассматривали классы, но все же поскольку это связано с массивами, то рассмотрим тут. Если что-то не понятно, то просто намотайте на ус и просто имейте в виду что есть такая возможность как передача в метод переменного количества аргументов (Varargs). Этот синтаксис стал доступен а Java 5. Так же стоит отметить, что данный синтаксис применим только к одномерным массивам.

Для примера рассмотрим метод возвращающий максимальное число из переданного в него одномерного массива чисел.

В строке 17 описан метод без использования синтаксиса Varargs. В строке 24 в описании метода используется синтаксис Varargs. Соответственно и вызываются эти методы по разному (строки 9 и 13 соответственно), хотя и выполняют абсолютно одну и ту же задачу, просто в случае использования синтаксиса Varargs код более читаем и понятен.

По существу в методе max_new numbers это тот же одномерный массив чисел и соответственно с ним можно работать как с массивом.

Поскольку классы и методы мы еще не изучали я немного поясню данный код.

Метод main() заканчивается на строке 15, то есть выполнение программы заканчивается на этой строке.

После строки 15 идет объявление методов max_old и max_new, которые вызываются в строках 9 и 13 соответственно.

Данная программа генерирует следующий вывод:

Отметим две важные особенности этой программы. Во-первых, как уже было сказано, внутри метода max_new() переменная numbers действует как массив. Это обусловлено тем, что numbers является массивом. Синтаксическая конструкция . просто указывает компилятору, что метод будет использовать переменное количество аргументов, и что эти аргументы будут храниться в массиве , на который ссылается переменная numbers.

Метод max_new() может вызываться с различным количеством аргументов, в том числе, и вовсе без аргументов. Аргументы автоматически помещаются в массив и ссылка на него передается переменной numbers. В случае отсутствия аргументов длина массива равна нулю .

Наряду с параметром переменной длины массив может содержать “нормальные” параметры . Однако параметр переменной длины должен быть последним параметром, объявленным в методе . Например, следующее объявление метода вполне допустимо:

Читать еще:  Удаление зараженных файлов браузера

int doIt ( int a, int b, double c, int . vals )

В данном случае первые три аргумента, указанные в обращении к методу doIt() , соответствуют первым трем параметрам. Все остальные аргументы считаются принадлежащими параметру vals.

Помните, что параметр vararg должен быть последним. Например, следующее объявление записано неправильно:

int doIt ( int a , int b , double c , int . vals , boolean stopFlag ) // Ошибка!

В этом примере предпринимается попытка объявления обычного параметра после параметра типа vararg, что недопустимо.

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

int doIt ( int a , int b , double c , int . vals , double . morevals ) // Ошибка!

Попытка объявления второго параметра типа vararg недопустима.

Рассмотрим еще одну простую программу с varargs представленную справа.

В строке 9 происходит вызов метода varArgs, без аргумента переменной длины, то есть он отсутствует.

В строке 10 в varargs передан один аргумент, ав строке 12 три.

Так же, как видите, как аргумент varargs можно передавать и одномерный массив (строка 15).

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

Данная программа сгенерирует следующий вывод:

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

Если сказать по простому, то перегрузка методов, это объявление двух или более методов с одинаковым названием, но разным количеством и/или разными типами данных принимаемых аргументов. Это позволяет использовать одно название метода, но передавать туда аргументы разных типов данных и/или разное количество аргументов. Лучше все это посмотреть на примере и тогда все станет более или менее ясно.

В строках с 9 по 14 происходит вызов перегруженного метода varArgs.

Строка 11 содержит ошибку, так как нет метода varArgs, который бы принимал как аргументы строку и varargs параметры типа double. Это строку я вставил для пущего понимания происходящего.

С 17 строки идет объявление перегруженного метода varArgs.

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

Хотя сейчас это может быть и не особо понятно, но на подкорочке пусть будет.

Программа генерирует следующий вывод:

На заметку! Метод, поддерживающий varargs, может быть перегружен также методом, который не поддерживает эту функциональную возможность (строка 23). Например, в приведенной программе метод varArgs() перегружен методом varArgs(int numbers). Эта специализированная версия вызывается только при наличии одного аргумента int. В случае передаче методу двух и более аргументов int программа будет использовать varargs-версию метода varArgs(int. numbers) определенную в строке 27.

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

Например, рассмотрим следующую программу:

Вызов метода varArgs в строке 16 вызовет ошибку компиляции. Поскольку параметр типа vararg может быть пустым, этот вызов может быть преобразован в обращение к varArgs(int. ), varArgs(double…) или varArgs(boolean. ). Все варианты допустимы. Поэтому вызов принципиально неоднозначен.

Если же мы закомментируем допустим описание методов для double… и boolean… , а так же их вызовы и оставим только описание метода int… и его вызов с параметрами и без то все откомпилируется и будет работать нормально.

В данном случае программа сгенерирует следующий вывод:

Рассмотрим еще один пример неопределенности. Следующие перегруженные версии метода varArgs() изначально неоднозначны, несмотря на то, что одна из них принимает обычный параметр:

static void varArgs ( int . v )
static void varArgs ( int n, int . v )

Хотя списки параметров метода varArgs() различны, компилятор не имеет возможности разрешения следующего вызова:

Должен ли он быть преобразован в обращение к varArgs(int. ) с одним аргументом переменной длины или в обращение к varArgs(int, int. ) без аргументов переменной длины? Компилятор не имеет возможности ответить на этот вопрос. Таким образом ситуация неоднозначна.

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

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

Программа может сгенерировать такой вывод:

За сим с массивами пока заканчиваем, но мы с ними еще не раз встретимся.

Вводный курс. Язык программирования Java

11. Класс Arrays. Работа с массивами

Большая часть методов работы с массивами определена в специальном классе Arrays пакета java.util. Ряд методов определены в классах java.lang.Object и java.lang.System.

На практике наиболее часто в основном используются методы класса java.util.Arrays, а также несколько методов классов java.lang.Object и java.lang.System. Указанные методы представлены ниже.

Методы перегружены для всех примитивных типов

[]b=Arrays.copyOf([]a, int newLength)

[]a – исходный массив

[]b – новый массив

newLength – длина нового массива

[]b=Arrays.copyOfRange ([]a, int index1, int index2)

копирование части массива,

Читать еще:  Революционный прорыв: Емкость аккумуляторов вырастет в разы

[]a – исходный массив

[]b – новый массив

index1, index2– начальный и конечный индексы копирования

java.lang.System.arraycopy([] a, indexA , []b, indexB, count)

[]a – исходный массив

[]b – новый массив

indexA-начальный индекс копирования исходного массива

indexB-начальный индекс нового массива

count– количество элементов копирования

[]b= a.java.lang.Object.clone()

[]a – исходный массив

[]b – новый массив

Arrays.sort([]a)

Сортировка. Упорядочивание всего массива в порядке возрастания

Arrays.sort([]a,index1,index2)

Сортировка части массива

в порядке возрастания

Arrays.sort([]a, Collections.reverseOrder());

Сортировка. Упорядочивание всего массива в порядке убывания

Boolean f=Arrays.equals([]a,[]b)

String str=Arrays.toString([]a);

Вывод одномерных массивов. Все элементы представлены в виде одной строки

int index=Arrays.binarySearch([]a,элемент a)

поиск элемента методом бинарного поиска

Arrays.fill([]a, элемент заполнения)

заполнение массива переданным значением

Boolean f=Arrays.deepEquals([]a, []b)

сравнение двумерных массивов

List Arrays.asList( []a);

Перевод массива в коллекцию

Для работы с классом необходимо подключить библиотеку java.util.Arrays.

Методы работы с массивами

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

Метод java.util.Arrays.copyOf()

Arrays.copyOf возвращает массив-копию новой длины. Если новая длина меньше исходной, то массив усекается до этой длины, а если больше, то дополняется значениями по умолчанию соответствующего типа.

[]b=Arrays.copyOf([]a, int newLength),

[]a – исходный массив

[]b – новый массив

newLength – длина нового массива

Пример 1.

длина массива a:6
длина массива b: 6
массив a
0.0 1.0 2.0 3.0 4.0 5.0
новая длина массива b: 3
массив b
0.0 1.0 2.0

Пример 2.

массив flag1
true true true
массив flag2
false false false false false
длина массива flag2: 5
массив flag2
true true true false false

Метод java.util. Arrays.copyOf()

Arrays.copyOfRange возвращает массив-копию новой длины, при этом копируется часть оригинального массива от начального индекса до конечного –1.

[]b=Arrays.copyOfRange ([]a, int index1, int index2),

[]a – исходный массив

[]b – новый массив

index1, index2– начальный и конечный индексы копирования

Пример.

Дни недели:
Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье
Рабочие дни
Понедельник Вторник Среда Четверг Пятница

Метод arraycopy() из класса System

Быстродействие метода System.arraycopy() выше по сравнению с использованием цикла for для выполнения копирования. Метод System.arraycopy( ) перегружен для обработки всех типов.

java.lang.System.arraycopy([] a, indexA , []b, indexB, count),

[]a – исходный массив

[]b – новый массив

indexA-начальный индекс копирования исходного массива

indexB-начальный индекс нового массива

count– количество элементов копирования

Пример.

Пример.

Метод clone() из класса Object

[]b= a.java.lang.Object.clone();

[]a – исходный массив

[]b – новый массив

Пример.

Сортировка массивов

Метод Arrays.sort([]a)

Метод sort() из класса Arrays использует усовершенствованный алгоритм Быстрой сортировки (Quicksort), который эффективен для большинства набора данных. Метод упорядочивает весь массив в порядке возрастания значений элементов.

Arrays.sort([]a),

[]a – исходный массив, после работы метода массив будет содержать упорядоченные значения элементов в порядке возрастания.

Пример.

Метод Arrays.sort([]a,index1,index2)

выполняет сортировку части массива по возрастанию массива от index1 до index2 минус единица

Arrays.sort([]a,index1,index2),

[]a – исходный массив

index1, index2 – начальный и конечный индексы, определяющие диапазон упорядочивания элементов по возрастанию.

Пример.

Сортировка массива по убыванию

Arrays.sort([]a, Collections.reverseOrder());

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

Пример.

15,39 1,54 17,47 15,50 3,83 16,43 18,87 15,54 8,23 12,97

Массив,отсотированный по убыванию

18,87 17,47 16,43 15,54 15,50 15,39 12,97 8,23 3,83 1,54

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

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

Класс Object имеет метод equals , который наследуется массивами и не является перегруженным и сравнение идет по адресам объектов, а не по содержимому. Метод equals перегружен только в классе Arrays . Отсюда вытекает правило сравнения массивов:

  • a == b сравниваются адреса массивов
  • a.equals(b) сравниваются адреса массивов
  • Arrays.equals(a, b) сравнивается содержимое массивов
  • Arrays.deepEquals(a, b) сравнивается содержимое многомерных массивов

Boolean f=Arrays.equals([]a,[]b);

Метод вернет true, если содержимое массивов равно, в противном случае false.

Пример.

Вывод одномерных массивов

Имеется достаточно удобный метод вывода данных одномерного массива – Arrays.toString([]a, который возвращает строковое представление массива со строковым представлением элементов, заключенных в квадратные скобки.

String str=Arrays.toString([]a);

Пример.

Это адрес: [Ljava.lang.String;@1db9742

Это значения: [Красный, Синий, Зеленый]

До сортировки: [7, 2, 9, 1, 0, 3, 4, 8, 5, 6]

После сортировки: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Вывод многомерных массивов

Для вывода многомерных массивов метод Arrays.deepToString.

String str= Arrays.deepToString([][]a);

Пример.

массив a: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

массив ch: [[а, б, в], [г, д, е], [ё, ж, з]]

Бинарный поиск элемента в одномерном массиве

Бинарный поиск – алгоритм поиска элемента в отсортированном массиве. Алгоритм основывается на принципе последовательного деления массива пополам.

int index=Arrays.binarySearch([]a,элемент x),

х – искомое значение

index – индекс элемента в массиве, если поиск успешный,

отрицательное число – если в массиве элемент не найден

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

Пример.

Массив= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

искомое значение = 5

Пример.

Массив= [август, апрель, декабрь, июль, июнь, май, март, ноябрь, октябрь, сентябрь, февраль, январь]

искомое значение = март

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

Метод Arrays.fill() позволяет заполнить массив одинаковыми данными.

Имеется два метода

Читать еще:  Компьютерные черви, принцип функционирования и классификация.

Arrays.fill([]a, value);

Arrays.fill(a[], int index1, int index2, value),

[]a – заполняемый массив,

index1, index2- индексы диапазона заполнения,

Пример.

До заполнения a: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

До заполнения b: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

До заполнения bool: [false, false, false, false, false, false, false, false, false, false]

После заполнения a: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

После заполнения b: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 2.0, 2.0]

После заполнения: bool[true, true, true, true, true, false, false, false, false, false]

15. Java — Массивы

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

Вместо объявления отдельных переменных, таких как number0, number1, . и number99, Вы объявляете одну переменную массива, например, numbers и используете numbers[0], numbers[1], . и numbers[99], для отображения отдельных переменных.

Данная статья ознакомит Вас как в Java объявить массив переменных, создать и обрабатывать массив с помощью индексированных переменных.

Содержание

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

Чтобы использовать массив в программе, необходимо объявить переменную для ссылки на массив, и Вы должны указать тип массива, который может ссылаться на переменную. Синтаксис для объявления переменной массива:

Примечание: стиль dataType[] arrayRefVar является предпочтительным. Стиль dataType arrayRefVar[] происходит из языка C/C++ и был принят в Java для C/C++-программистов.

Пример

Следующие фрагменты кода примеры использования данного синтаксиса:

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

В Java создать массив можно с помощью оператора new с помощью следующего синтаксиса:

Вышеуказанное объявление делает две вещи:

  • Создает массив, используя new dataType[arraySize];
  • Ссылка на недавно созданный массив присваивается переменной arrayRefVar.

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

В качестве альтернативы массивы в Java можно создавать следующим образом:

Элементы массива доступны через индекс. Отсчет индексов ведется от 0; то есть они начинают от 0 и до arrayRefVar.length-1.

Пример

Следующий оператор объявляет массив переменных myList, создает массив из 10 элементов типа double и присваивает ссылку myList:

Изображение отображает массив myList. Здесь myList имеет десять значений double и индексы от 0 до 9.

Работа с массивами

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

Пример

Полный пример, показывающий, как создавать, инициализировать и обработать массив:

Получим следующий результат:

Цикл foreach

JDK 1.5 представила новый цикл for, известный как цикл foreach или расширенный цикл for, который позволяет последовательно пройти весь массив без использования индекса переменной.

Пример

Следующий код отображает все элементы в массиве myList:

Получим следующий результат:

Передача массива в метод

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

Его можно вызвать путем передачи массива. Например, следующий оператор вызывает метод printArray для отображения 3, 1, 2, 6, 4 и 2:

Возврат массива из метода

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

Методы для массива

Класс java.util.Arrays содержит различные статические методы для поиска, сортировки, сравнения и заполнения элементов массива. Методы перегружаются для всех примитивных типов.

Пример 1: создание, объявление переменных, определение (выделение памяти) и инициализация массива

В качестве примера возьмем тип данных int. Вы же можете использовать любой другой тип данных.

Пример 2: длина массива

Узнать размер массива в Java можно с помощью метода length(). Данный метод позволяет определить размерность массива.

Получим следующий результат:

Пример 3: максимальный элемент массива

Простые способы для того, чтобы найти максимальное число в массиве в Java. Сперва воспользуемся методом Math.max().

Получим следующий результат:

Ещё один пример нахождения максимального числа в массиве в Java. Здесь мы не будем использовать какие-либо методы.

Получим следующий результат:

Пример 4: минимальный элемент массива

Написанный ниже код практически ничем не отличается от кода, описанного в примере 3. Он в точности наоборот, просто здесь мы ищем минимальное число в массиве в Java. В первом способе воспользуемся методом Math.min().

Получим следующий результат:

Ещё один пример нахождения максимального числа в массиве в Java. Здесь мы не будем использовать какие-либо методы.

Получим следующий результат:

Пример 5: сумма массива

В этом примере рассмотрим как получить сумму элементов массива в Java.

Получим следующий результат:

А в этом примере используем улучшенный цикл for, чтобы найти сумму массива.

Получим следующий результат:

Пример 6: вывод массива

В данном примере рассмотрим как вывести массив на экран в Java.

Получим следующий результат:

Пример 7: вывод четных и нечетных элементов массива

В примере показано как вывести четные и нечетных элементы массива в Java.

Получим следующий результат:

Пример 8: вывод элементов массива с четным и нечетным индексом

В примере показано как вывести на экран элементы массива с четным и нечетным индексом.

голоса
Рейтинг статьи
Ссылка на основную публикацию
Статьи c упоминанием слов: