Java. Масиви рядків. Одновимірні та двовимірні масиви рядків. Ініціалізація масивів рядків. Приклади розв'язання задач
Масиви рядків у Java. Одновимірні та двовимірні масиви рядків. Ініціалізація масивів рядків. Приклади розв'язання задач
Пошук на інших ресурсах:
1. Поняття масиву рядків. Загальна форма оголошення одномірного масиву рядків
Як і будь-яка мова програмування, мова програмування Java може реалізовувати масиви рядків. Будь - який рядок у Java має тип String . Одномірний масив рядків має тип String[]. Двовимірний масив рядків має тип String[][].
Загальна форма оголошення та виділення пам'яті для одномірного масиву рядків
String[] arrayName = new String[size];
- String – вбудований Java клас, який реалізує рядок символів. Об'єкт типу String підтримує великий набір операцій, які можна переглянути туті тут ;
- arrayName - Ім'я об'єкта (примірника) типу String . Фактично, arrayName є посиланням на об'єкт типу String;
- size - Розмір масиву (кількість рядків, кількість елементів типу String ).
Оголошення одновимірного масиву рядків і виділення пам'яті йому можна продати і інакше
String[] arrayName;
arrayName = new String[size];
2. Яким чином оголошується одновимірний масив рядків? приклад
Нижче наведено приклад оголошення та використання одновимірного масиву рядків.
// оголошення одновимірного масиву рядків
String[] array = new String[5];
// Заповнення початковими значеннями
array[0] = "abcd";
array[1] = "Hello";
array[2] = ""; // Порожній рядок
array[3] = "bestprog";
array[4] = ";:\+ color: #008000;">// комбінація "\" замінюється на "\"
// Використання у виразах
arrayS[4] = arrayS[1] + " " + arrayS [3]; // arrayS[4] = "Hello bestprog"
arrayS[4] += ".net"; // arrayS[4] = "Hello bestprog.net"
Як видно з прикладу, робота з масивами рядків у Java є досить зручною і не потребує складних додаткових перетворень на їхню обробку.
3. Двовимірний масив рядків. Загальна форма
Можливо, у деяких завданнях виникне потреба в оголошенні двовимірного масиву рядків.
Загальна форма оголошення двовимірного масиву рядків:
String[][] matrName = new String[n][m];
- matrName - Ім'я об'єкта (посилання на об'єкт), який є двовимірним масивом типу String;
- n – кількість рядків у масиві matrName ;
- m – кількість стовпців у масиві matrName .
Можливий також інший спосіб оголошення та виділення пам'яті для двовимірного масиву рядків:
String[][] matrName; // оголошення посилання на двовимірний масив рядків
matrName = new String[n][m];
4. Приклад оголошення та використання двовимірного масиву рядків
Нижче наведено приклад оголошення та використання двовимірного масиву рядків
// оголошення двовимірного масиву рядків
String[][] matr = new String[2][3];
// Заповнення масиву значеннями
for
(int
i=0; ilength; i++)
for
(int
j=0; jlength; j++)
matrS[i][j] = "matrS[" + i + "][" +j + "]";
// Перевірка
String s;
s = matrS[0][0]; // s = "matrS[0][0]"
s = matrS[1][1]; // s = "matrS[1][1]"
5. Як визначається довжина масиву рядків? Властивість length. приклад
Щоб визначити кількість рядків у масиві використовується властивість length.
Для одномірних масивів кількість рядків n визначається так:
String[] arrayS = new String[25];
int
n;
n = array.length;
Для двовимірних масивів кількість рядків та стовпців визначається наступним чином
// matr - двовимірний масив рядків
String[][] matrS = new String[2][3];
int n, m;
n = matr.length; // n = 2 - кількість рядків
m = matr [0].length; // m = 3 – кількість стовпців
m = matr[1].length; // m = 3
6. Як здійснюється ініціалізація одновимірного масиву? приклад
Ініціалізація одновимірного масиву рядків така сама як ініціалізація одновимірного масиву будь-якого іншого типу.
// ініціалізація одновимірного масиву рядків
String[] M = "Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
>;
String s;
s = M[2]; // s = "Tuesday"
s = M[4]; // s = "Thursday"
7. Пошук заданого рядка в одновимірному масиві рядків.
// Пошук заданого рядка в масиві рядків
// оголошення масиву рядків
String M[] = new String[5];
String s = "Май"; // рядок, який потрібно знайти
boolean
f_is;
// Заповнення масиву значеннями
M[0] = "January";
M[1] = "February";
M[2] = "Май";
M[3] = "Жовтень";
M[4] = "December";
// пошук рядка
f_is = false;
for
(int
i=0;;
if (M[i]==s) f_is = true;
break;
>
// Висновок результату
if
(f_is)
System.out.println("Шуканий рядок є в масиві.");
else
System.out.println("Шуканого рядка немає в масиві.");
8. Сортування одновимірного масиву рядків за абеткою шляхом вставки.
Для порівняння двох рядків у лексикографічному порядку у класі String розроблено метод compareTo() .
int
compareTo(другий_рядок)
- , якщо другий рядок слідує після першого рядка в лексикографічному порядку;
- =0 якщо рядки однакові;
- >0 , якщо другий рядок слідує перед першим у лексикографічному порядку.
Фрагмент, який демонструє сортування масиву рядків методом вставки:
// Сортування масиву рядків методом вставки
String[] M = "abc",
"bde",
"fgh",
"abcd",
"bcdef",
"cdef",
"fghij",
"aaa"
>;
String s;
// сортування
for
(int
i=0;-1;
for
(int
j=i; j>=0;
if
(M[j].compareTo(M[j+1])>0) // обміняти M[j] та M[j+1] місцями
s = M[j];
M[j] = M[j+1];
M[j+1] = s;
>
// Висновок результату
for
(int
i=0;;
System.out.println(M[i]);
В результаті виконання наведеного вище коду, на екран буде виведено наступне
aaa
abc
abcd
bcdef
bde
cdef
fgh
fghij
9. Як здійснюється ініціалізація двовимірного масиву рядків?
Ініціалізація двовимірного масиву рядків нічим не відрізняється від ініціалізації двовимірного масиву будь-якого примітивного типу. Елементами масиву є звичайні рядки.
Нижче наведено приклад ініціалізації двовимірного масиву рядків з ім'ям M
// оголошення масиву M з початковою ініціалізацією
String M[][] = new
< "a1", "a2", "a3" >,
< "b1", "b2", "b3" >,
< "a1", "c2", "a1" >
>;
// Перевірка
String s;
s = M[0][1]; // s = "a2"
s = M[1][0]; // s = "b1"
10. Приклад підрахунку кількості входжень заданого рядка у двовимірному масиві рядків
// Обчислення кількості входжень заданого рядка у двовимірному масиві
// оголошення масиву M із початковою ініціалізацією
String M[][] = < "abcd", "abc", "bcd" >,
< "acd", "bcd", "abcd" >,
< "abc", "bc", "cde" >
>;
String s = "abc"; // рядок, кількість входжень якого потрібно обчислити
int
k = 0; // кількість входжень, результат
for
(int
i=0;;
for
(int
j=0;;
if
(M[i][j]==s)
k++;
// k = 2
11. Приклад заміни рядка у двовимірному масиві рядків
- двомірний масив рядків з ім'ям matr;
- рядок s1, який шукається для заміни;
- рядок s2, який замінює рядок s1.
Розробити програму, яка замінює рядок s1 у матриці matr на новий рядок s2 .
// оголошення двовимірного масиву рядків
String[][] matr = new String[2][3];
// заповнення матриці matr довільними значеннями
matrS[0][0] = "abc";
matrS[0][1] = "cba";
matrS[0][2] = "def";
matrS[1][0] = "abc";
matrS[1][1] = "fff";
matrS[1][2] = "qqq";
// заповнення значеннями рядків s1 та s2
String s1 = "abc"; // Замінний рядок
String s2 = "mmm"; // Замінний рядок
// цикл обчислення
for
(int
i=0;;
for
(int
j=0;;
if
(matrS[i][j]==s1)
matr[i][j] = s2;
// Висновок результату
for
(int
i=0;; i++)
for (int
j=0; jlength; j++)
System.out.print(matrS[i][j] + " ");
System.out.println();
>
В результаті виконання наведеного вище коду, на екран буде виведений наступний результат:
mmm cba def
mmm fff qqq
Пов'язані теми
Операції з масивами в Java
Будь-який Java-розробник знає, що створити чисте та ефективне рішення при роботі з масивами не завжди легко. Тим не менш, вони є центральним елементом екосистеми Java, і нам доведеться мати з ними справу кілька разів.
Тому добре мати «шпаргалку» — короткий виклад найпоширеніших процедур, які допоможуть нам швидко вирішити головоломку. Цей підручник стане в нагоді в таких ситуаціях.
2. Масиви та допоміжні класи
Перш ніж продовжити, корисно зрозуміти, що таке масив Java і як його використовувати. Якщо ви вперше працюєте з ним на Java, ми пропонуємо подивитись цей попередній пост, де ми розглянули всі основні концепції.
Зауважте, що основні операції, які підтримує масив, певним чином обмежені. Коли доходить до масивів, нерідко можна побачити складні алгоритми до виконання щодо простих завдань.
З цієї причини для більшості наших операцій ми будемо використовувати допоміжні класи та методи: клас Arrays, що надається Java, та клас ArrayUtils Apache.
Щоб включити останній до нашого проекту, нам потрібно додати залежність Apache Commons :
dependency>
groupId>org.apache.commonsgroupId>
artifactId>commons-lang3artifactId>
version>3.12.0version>
dependency>
Ми можемо перевірити останню версію цього артефакту на Maven Central.
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. Додайте новий елемент у масив
Як відомо, масиви містять фіксований розмір значень. Тому ми не можемо просто додати елемент та перевищити цей ліміт.
Нам потрібно почати з оголошення нового масиву більшого розміру та скопіювати елементи базового масиву на другий.
На щастя, клас Arrays надає зручний метод реплікації значень масиву в нову структуру іншого розміру:
int[]
newArray
=
Arrays.copyOf(array,
array.length
+
1);
newArray[newArray.length
-
1]
=
newItem;
За бажання, якщо клас ArrayUtils доступний у нашому проекті, ми можемо використовувати його метод add (або його альтернативу addAll ) для досягнення нашої мети в однорядковому виразі:
int[]
newArray
=
ArrayUtils.add(array,
newItem);
Як ми можемо собі уявити, цей метод не змінює вихідний об'єкт масиву; ми маємо привласнити його вихід нової змінної.
6. Вставте значення між двома значеннями
Через його характер індексованих значень вставка елемента в масив між двома іншими не є тривіальним завданням.
Apache вважав це типовим сценарієм і реалізував метод у своєму класі ArrayUtils для спрощення рішення:
int[]
largerArray
=
ArrayUtils.insert(2,
array,
77);
Ми повинні вказати індекс, який ми хочемо вставити значення, і на виході буде новий масив, що містить більшу кількість елементів.
Останній аргумент є змінним аргументом (він же vararg), тому ми можемо вставити будь-яку кількість елементів у масив.
7. Порівняйте два масиви
Незважаючи на те, що масиви є Object і, отже, надають метод equals, вони використовують його реалізацію за умовчанням, покладаючись лише на рівність посилань.
У будь-якому випадку ми можемо викликати метод equals java.util.Arrays , щоб перевірити, чи містять два об'єкти масиву однакові значення: ``
boolean
єEqual
=
Arrays.equals(array1,
array2);
Цей метод не ефективний для зубчастих масивів. Відповідним методом перевірки рівності багатовимірних структур є метод Arrays.deepEquals.
8. Перевірте, чи порожній масив
Це нескладне призначення з огляду на те, що ми можемо використовувати атрибут довжини масивів:
boolean
isEmpty
=
array
==
null
||
array.length
==
0;
Більше того, у нас також є null-safe метод у допоміжному класі 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 :
ArrayUtils.shuffle(array);
Це метод void, який працює з фактичними значеннями масиву.
10. Блокування та розпакування масивів
Ми часто стикаємося з методами, які підтримують лише масиви на основі Object.
Знову нагоді допоміжний клас ArrayUtils, щоб отримати упаковану версію нашого примітивного масиву:
Integer[]
list
=
ArrayUtils.toObject(array);
Можлива і зворотна операція:
Integer[]
objectArray
=
3,
5,
2,
5,
14,
4
>;
int[]
array
=
ArrayUtils.доPrimitive(objectArray);
11. Видалити дублікати з масиву
Найпростіший спосіб видалити дублікати - перетворити масив у реалізацію Set.
Як відомо, Collections використовує Generics і, отже, не підтримує примітивні типи.
З цієї причини, якщо ми не обробляємо масиви на основі об'єктів, як у нашому прикладі, нам спочатку потрібно запакувати наші значення:
// Box
Integer[]
list
=
ArrayUtils.toObject(array);
// Remove duplicates
SetInteger>
set
=
new
HashSetInteger>(Arrays.asList(list));
// Create array and unbox
return
ArrayUtils.доPrimitive(set.toArray(new
Integer[set.size()]));
Крім того, якщо нам потрібно зберегти порядок наших елементів, ми повинні використовувати іншу реалізацію Set, таку як LinkedHashSet.
12. Як роздрукувати масив
Як і у випадку з методом equals , функція масиву toString використовує стандартну реалізацію, надану класом Object , що не дуже корисно.
Класи Array і ArrayUtils поставляються зі своїми реалізаціями для перетворення структур даних в легкочитаний String.
Крім трохи іншого формату, який вони використовують, найбільш важливою відмінністю є те, як вони обробляють багатовимірні об'єкти.
Клас Java Util надає два статичні методи, які ми можемо використовувати:
- toString : погано працює із зубчастими масивами
- deepToString: підтримує будь-які масиви на основі об'єктів, але не компілюється з аргументами примітивного масиву.
З іншого боку, реалізація Apache пропонує єдиний метод toString, який працює коректно в будь-якому випадку:
String
arrayAsString
=
ArrayUtils.toString(array);
13. Зіставте масив з іншим типом
Часто буває корисно застосувати операції до всіх елементів масиву, можливо, перетворивши їх на інший тип об'єкта.
Пам'ятаючи про це, ми спробуємо створити гнучкий допоміжний метод, використовуючи Generics:
public
static
T,
U>
U[]
mapObjectArray(
T[]
array,
FunctionT,
U>
function,
ClassU>
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 у нашому проекті, ми можемо відмовитись від аргументу Function і створити метод для кожного зіставлення, яке нам потрібно виконати.
Тепер ми можемо повторно використати наш універсальний метод для різних операцій. Давайте створимо два тестові випадки, щоб проілюструвати це:
@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, щоб виконати зіставлення для нас.
Спершу нам потрібно перетворити масив у Stream of Object s. Ми можемо зробити це за допомогою методу Arrays.stream.
Наприклад, якщо ми хочемо зіставити наші значення int з уявленням користувача String , ми реалізуємо це:
String[]
stringArray
=
Arrays.stream(array)
.mapToObj(value
->
String.format("Value: %s",
value))
.toArray(String[]::new);
14. Фільтрація значень у масиві
Фільтрування значень із колекції — звичайне завдання, яке нам, можливо, доведеться виконувати більше одного разу.
Це пов'язано з тим, що в той час, коли ми створюємо масив, який отримуватиме значення, ми не можемо бути впевнені в його остаточному розмірі. Тому ми знову покладатимемося на підхід Stream.
Уявіть, що ми хочемо видалити всі непарні числа з масиву:
int[]
evenArray
=
Arrays.stream(array)
.filter(value
->
value
%
2
==
0)
.toArray();
15. Інші загальні операції з масивами
Є, звичайно, безліч інших операцій із масивами, які нам можуть знадобитися.
Крім показаних у цьому посібнику, ми докладно розглянули інші операції у спеціальних повідомленнях:
- Перевірте, чи містить масив Java значення
- Як скопіювати масив у Java
- Видалення першого елемента масиву
- Знаходження мінімуму та максимуму в масиві за допомогою Java
- Знайдіть суму та середнє значення в масиві Java
- Як інвертувати масив у Java
- Об'єднання та поділ масивів та колекцій у Java
- Об'єднання різних типів колекцій у Java
- Знайдіть у масиві всі пари чисел, які у сумі дають задану суму
- Сортування у Java
- Ефективний калькулятор частоти слів у Java
- Сортування вставками в Java
16. Висновок
Масиви - одна з основних функцій Java, і тому дуже важливо розуміти, як вони працюють, і знати, що ми можемо і чого не можемо робити з ними.
У цьому посібнику ми дізналися, як правильно обробляти операції з масивами у поширених сценаріях.
Як завжди, повний вихідний код робочих прикладів доступний у нашому репозиторії Github.
- 1. Огляд
- 2. Масиви та допоміжні класи
- 3. Отримати перший та останній елемент масиву
- 4. Отримати випадкове значення з масиву
- 5. Додайте новий елемент до масиву
- 6. Вставте значення між двома значеннями
- 7. Порівняйте два масиви
- 8. Перевірте, чи порожній масив
- 9. Як перетасувати елементи масиву
- 10. Блокування та розпакування масивів
- 11. Видалити дублікати з масиву
- 12. Як роздрукувати масив
- 13. Зіставте масив з іншим типом
- 14. Фільтрація значень у масиві
- 15. Інші загальні операції з масивами
- 16. Висновок