CodeGym /Blog Java /Random-PL /Coś o tablicach
Autor
Volodymyr Portianko
Java Engineer at Playtika

Coś o tablicach

Opublikowano w grupie Random-PL
Cześć! Wcześniej na twoim szkoleniu pracowaliśmy z pojedynczymi obiektami (i typami pierwotnymi). Ale co, jeśli musimy pracować z całą grupą obiektów zamiast tylko jednego? Załóżmy na przykład, że chcemy stworzyć listę urodzin wszystkich pracowników naszej firmy. Powinien zawierać 30 ciągów sformatowanych w następujący sposób: „Sarah Huffman, 25 stycznia” Skorzystamy ze specjalnej struktury danych zwanej tablicą . Jeśli porównamy tablicę z rzeczywistym obiektem, jest ona bardzo podobna do skarbca bankowego ze skrytkami depozytowymi: Coś o tablicach - 1tablica również składa się z „skrzynek”. Do każdego pudełka możesz włożyć coś (element). Aby uzyskać dostęp do elementu, musisz znać jego numer skrzynki (indeks). W ten sposób tworzona jest tablica:

public class Main {

   public static void main(String[] args) {

       String [] birthdays = new String[10];
      
   }
}
Tutaj tworzymy tablicę zawierającą 10 elementów. Możesz od razu zauważyć niektóre cechy tablicy:
  1. Przechowuje elementy dobrze zdefiniowanego typu danych . Jeśli utworzymy tablicę String, nie możemy w niej przechowywać niczego innego. Typ danych jest określany podczas tworzenia tablicy . Tym różni się od skrytki depozytowej (w której klient może przechowywać to, na co ma ochotę).

  2. Jej rozmiar musi być określony podczas tworzenia tablicy . Nie można jej później wskazać ani zmienić jej rozmiaru po utworzeniu tablicy .
O tym, że tworzymy tablicę, świadczą nawiasy kwadratowe po obu stronach wyrażenia. Można je podać przed lub po nazwie zmiennej referencyjnej. Tak czy inaczej zadziała:

String [] birthdays = new String[10];
String birthdays [] = new String[10];
Jeśli chcesz zapisać coś w tablicy, musisz określić indeks pola, w którym zostanie wpisana wartość. Pola w tablicy są numerowane począwszy od 0. Liczenie od zera jest bardzo powszechną praktyką w programowaniu. Im szybciej się do tego przyzwyczaisz, tym lepiej :) Coś o tablicach - 2 Oznacza to, że jeśli chcesz umieścić jakąś wartość w pierwszym polu , robisz to:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
   }
}
Teraz urodziny Jana są przechowywane w pierwszej komórce naszej tablicy urodzin pracowników: Możesz dodać inne wartości w podobny sposób:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";
   }
}
Zauważ, że dodaliśmy urodziny Rosie do ósmego pudełka (nie zapomniałeś, dlaczego pudełko nr 7 jest ósmym pudełkiem, prawda?) . Widać, że nie wypełniliśmy wszystkich pozostałych komórek. Nie musimy wpisywać wartości do tablicy po kolei. Nie ma takiego wymogu. Oczywiście pisanie elementów w kolejności znacznie ułatwia śledzenie, ile pól jest wolnych, a ile jest zajętych, i zapobiega powstawaniu „dziur” w tablicy. Jeśli chcesz uzyskać zawartość jednej ze skrytek, to (podobnie jak w przypadku skrytki depozytowej) musisz znać jej numer. Oto jak to się robi:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";

       String rosieBirthday = birthdays[7];
       System.out.println(rosieBirthday);
   }
}
Dane wyjściowe konsoli: Rosie Mills, 3 stycznia Stworzyliśmy Stringzmienną i powiedzieliśmy kompilatorowi: „Znajdź pole o indeksie 7 w tablicy birthdays i przypisz zawartą tam wartość Stringzmiennej rosieBirthday ”. I tak właśnie się stało. Podczas pracy z tablicami możemy łatwo znaleźć ich długość za pomocą specjalnej właściwości: length .

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[7] = "Rosie Mills, January 3";

       int birthdaysLength = birthdays.length;
       System.out.println(birthdaysLength);
   }
}
Dane wyjściowe konsoli: 10 Uwaga: lengthWłaściwość przechowuje rozmiar tablicy, a nie liczbę zapełnionych pól. Nasza tablica przechowuje tylko 3 wartości, ale podczas jej tworzenia wskazaliśmy jej rozmiar jako 10. I to jest dokładnie wartość, którą lengthzwraca pole. Dlaczego miałoby się to przydać? Cóż, załóżmy, że chcesz wyświetlić listę wszystkich urodzin (aby sprawdzić, czy nikt nie został pominięty). Możesz to zrobić w jednej prostej pętli:

public class Main {

   public static void main(String[] args) {

       String birthdays [] = new String[10];
       birthdays[0] = "Jana Russell, March 12";
       birthdays[1] = "Landon Chan, May 18";
       birthdays[2] = "Jeremiah Leonard, July 12";
       birthdays [3] = "Kenny Russo, September 7";
       birthdays[4] = "Tommie Barnes, November 9";
       birthdays [5] = "Roman Baranov, August 14";
       birthdays [6] = "Chanice Andersen, April 1";
       birthdays[7] = "Rosie Mills, January 3";
       birthdays [8] = "Keenan West, October 19";
       birthdays [9] = "Abraham McArthur, May 3";

       for (int i = 0; i < birthdays.length; i++) {
           System.out.println(birthdays[i]);
       }
   }
}
W pętli deklarujemy zmienną i, która jest inicjowana na zero. Przy każdym przejściu pobieramy element o indeksie i z naszej tablicy i wyświetlamy jego wartość. Pętla wykona 10 iteracji, a i wzrośnie od 0 do 9 — a tak się składa, że ​​liczby są indeksami elementów naszej tablicy! W rezultacie wyświetlimy wszystkie wartości od birthdays[0] do birthdays[9] Właściwie istnieje inny sposób na utworzenie tablicy. Na przykład możesz utworzyć tablicę ints w następujący sposób:

public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
   }
}
Ta technika nazywa się „inicjowaniem skrótu”. Jest to dość wygodne, ponieważ jednocześnie tworzymy tablicę i wypełniamy ją wartościami. Nie musimy jawnie określać rozmiaru tablicy: przy inicjalizacji skrótu lengthpole jest ustawiane automatycznie.

public class Main {

   public static void main(String[] args) {
       int numbers [] = {7, 12, 8, 4, 33, 79, 1, 16, 2};
       System.out.println(numbers.length);
   }
}
Dane wyjściowe konsoli: 9 Teraz trochę o tym, jak tablice są przechowywane w pamięci. Powiedzmy, że mamy tablicę trzech Catobiektów:

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");
   }
}
Musisz tutaj zrozumieć kilka rzeczy:
  1. W przypadku prymitywów tablica przechowuje zestaw określonych wartości (np. ints). W przypadku obiektów tablica przechowuje zbiór referencji .
    Tablica catsskłada się z trzech elementów, z których każdy jest odniesieniem do Catobiektu. Każde z odwołań wskazuje adres pamięci, w której przechowywany jest odpowiedni obiekt.

  2. Elementy tablicy są ułożone w jednym bloku w pamięci. Ma to na celu umożliwienie szybkiego i sprawnego dostępu do nich.
W ten sposób catsodwołuje się do bloku pamięci, w którym przechowywane są wszystkie obiekty (elementy tablicy). Cats[0]odwołuje się do określonego adresu w tym bloku. Coś o tablicach - 3 Ważne jest, aby zrozumieć, że tablica nie tylko przechowuje obiekty: jest sama w sobie obiektem. To prowadzi nas do pytania, czy możemy tworzyć nie tylko tablice ciągów znaków lub liczb, ale także tablice tablic . Odpowiedź brzmi: tak, możemy! Tablica może przechowywać dowolne obiekty, w tym inne tablice. Taka tablica nazywana jest dwuwymiarową . Gdybyśmy mieli go przedstawić wizualnie, byłby bardzo podobny do zwykłego stołu. Załóżmy, że chcemy utworzyć tablicę 3 tablic , z których każda może przechowywać 10 ints. Wyglądałoby to tak:
Coś o tablicach - 4
Każda linia reprezentuje inttablicę. Pierwsza tablica zawiera liczby od 1 do 10, druga tablica — od -1 do -10, a trzecia — zbiór liczb losowych. Każda z tych tablic jest przechowywana w polach naszej dwuwymiarowej tablicy. W kodzie inicjalizacja dwuwymiarowej tablicy wygląda następująco:

public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
}
Nasze dwuwymiarowe tablice koty przechowują 3 tablice z 5 polami w każdej tablicy. Gdybyśmy chcieli umieścić obiekt w trzecim polu drugiej tablicy, zrobilibyśmy to w następujący sposób:

public static void main(String[] args) {
   Cat[][] cats = new Cat[3][5];
   cats[1][2] = new Cat("Fluffy");
}
[1]wskazuje drugą tablicę i [2]wskazuje trzecie pole tej tablicy. Ponieważ tablica dwuwymiarowa składa się z kilku tablic, w celu iteracji po niej i wyświetlenia wszystkich jej wartości (lub wypełnienia wszystkich jej elementów) potrzebujemy zagnieżdżonej pętli:

for (int i = 0; i < cats.length; i++) {
   for (int j = 0; j < cats[i].length; j++) {
       System.out.println(cats[i][j]);
   }
}
W pętli zewnętrznej (zmienna i) iterujemy po wszystkich tablicach w naszej dwuwymiarowej tablicy. W pętli wewnętrznej (zmienna j) przechodzimy przez wszystkie elementy każdej tablicy. W rezultacie koty[0][0] (pierwsza tablica, pierwszy element) zostaną wyświetlone jako pierwsze, a następnie koty[0][1] (pierwsza tablica, drugi element). Po przejrzeniu pierwszej tablicy wyświetlimy koty[1][0] , koty[1][1] , koty[1][2] itd. Nawiasem mówiąc, tablice dwuwymiarowe również obsługują skrótowa inicjalizacja:

int[][] numbers = {{1,2,3}, {4,5,6}, {7,8,9}};
Zwykle zadeklarowalibyśmy dwuwymiarową tablicę numbersjako int[3][3], ale ten skrót pozwala nam natychmiast określić wartości. Dlaczego potrzebujesz tablicy dwuwymiarowej? Cóż, możesz użyć jednego, aby łatwo odtworzyć słynną grę „Battleship”: Coś o tablicach - 5 w „Battleship” strukturę pola gry można łatwo opisać: dwuwymiarową tablicę 10 tablic po 10 elementów każda. Tworzysz dwie takie tablice (jedną dla siebie i jedną dla przeciwnika)

int[][] battleshipBoard1 = new int[10][10];
int[][] battleshipBoard2 = new int[10][10];
użyj pewnych wartości (np. liczb lub symboli), aby wypełnić elementy odpowiadające lokalizacji twoich statków, a następnie po kolei wywołuj współrzędne dla określonych elementów:
  • plansza pancernika1[0][2]!
  • Chybić! plansza pancernika2[2][4]!
  • Uderzyć!
  • plansza pancernika2[2][5]!
  • Uderzyć!
  • pancernikBoard2[2][6]!,
  • Zatopiony!
To kończy nasze pierwsze wprowadzenie do tablic, ale to dopiero początek naszej interakcji z nimi. Na kolejnych lekcjach zobaczymy ciekawe sposoby ich wykorzystania, a także dowiemy się, jakie wbudowane funkcje ma Java, aby wygodniej pracować z tą strukturą danych :)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION