Menu
Coddy logo textTech

Rekordy (Java 16+)

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 51 z 87.

Podczas tworzenia prostych klas przechowujących dane często piszesz powtarzalny kod szablonowy: pola prywatne, konstruktor, metody pobierające, toString(), equals() i hashCode(). W Java 16 wprowadzono rekordy, aby wyeliminować tę żmudną pracę.

Rekord to specjalna klasa przeznaczona do przechowywania niezmiennych danych. Deklarujesz go za pomocą słowa kluczowego record, po którym następuje lista komponentów:

record Person(String name, int age) { }

// Ta jedna linia automatycznie zapewnia:
// - pola private final: name i age
// - konstruktor: Person(String name, int age)
// - metody dostępowe: name() i age()
// - toString(), equals() i hashCode()

Korzystanie z rekordu jest proste:

Person p = new Person("Alice", 30);
System.out.println(p.name());    // Alice
System.out.println(p.age());     // 30
System.out.println(p);           // Person[name=Alice, age=30]

Zwróć uwagę, że metody dostępowe nie używają przedrostka get: ich nazwy są po prostu takie same jak nazwy pól. Rekordy są niejawnie final, więc nie można ich rozszerzać. Wszystkie pola również są final, dzięki czemu rekordy są z natury niezmienne.

W razie potrzeby możesz dodawać własne metody i nadpisywać te generowane automatycznie. Możesz również dodać walidację w konstruktorze kompaktowym:

record Person(String name, int age) {
    public Person {
        if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    }
}

Rekordy idealnie sprawdzają się w przypadku obiektów DTO, odpowiedzi API lub w każdej sytuacji, gdy potrzebujesz prostego, niemodyfikowalnego kontenera danych bez pisania powtarzalnego kodu.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system rezerwacji biletów na filmy, który pokazuje elegancję rekordów w Java. Zobaczysz, jak rekordy eliminują powtarzalny kod, a jednocześnie pozwalają dodawać własne metody i walidację.

Rozmieścisz swój kod w trzech plikach:

  • Movie.java: Utwórz rekord reprezentujący film z trzema komponentami: title (String), genre (String) i durationMinutes (int). Dodaj własną metodę o nazwie getFormattedDuration(), która zwraca czas trwania w czytelnym formacie: [hours]h [minutes]m (na przykład 142 minuty to 2h 22m). Użyj dzielenia całkowitego i operatora modulo, aby obliczyć liczbę godzin i pozostałych minut.
  • Ticket.java: Utwórz rekord reprezentujący bilet na film z trzema komponentami: movie (Movie), seatNumber (String) i price (double). Dodaj konstruktor kompaktowy, który sprawdza cenę: jeśli cena jest mniejsza lub równa zero, rzuć wyjątek IllegalArgumentException z komunikatem Price must be positive. Dodaj także własną metodę o nazwie printTicket(), która zwraca wielowierszowy ciąg znaków:
    ========== TICKET ==========
    Movie: [movie title]
    Genre: [movie genre]
    Duration: [formatted duration from movie]
    Seat: [seatNumber]
    Price: $[price]
    ============================
  • Main.java: Połącz elementy swojego systemu rezerwacji! Otrzymasz pięć danych wejściowych: tytuł filmu (String), gatunek (String), czas trwania w minutach (int), numer miejsca (String) i cenę biletu (double).

    Utwórz rekord Movie z pierwszych trzech danych wejściowych, a następnie utwórz rekord Ticket z filmem, numerem miejsca i ceną. Wypisz wynik wywołania metody printTicket() na swoim bilecie.

Otrzymasz kolejno pięć danych wejściowych: tytuł filmu, gatunek, czas trwania (w minutach), numer miejsca i cenę.

Zwróć uwagę, o ile czytelniejsze są rekordy w porównaniu z tradycyjnymi klasami: nie trzeba pisać konstruktorów, getterów, toString(), equals() ani hashCode(). Konstruktor kompaktowy pozwala dodać walidację bez powtarzania przypisań pól, a w razie potrzeby nadal możesz dodawać własne metody!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dane wejściowe
        String title = scanner.nextLine();
        String genre = scanner.nextLine();
        int durationMinutes = Integer.parseInt(scanner.nextLine());
        String seatNumber = scanner.nextLine();
        double price = Double.parseDouble(scanner.nextLine());
        
        // TODO: Utwórz rekord Movie z polami title, genre i durationMinutes
        
        // TODO: Utwórz rekord Ticket z filmem, seatNumber i price
        
        // TODO: Wypisz bilet za pomocą metody printTicket()
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online