Məzmuna keç
Educora
İrəli22 dəq12 / 18

Müasir Java və layihə: şagird jurnalı

record, var, lambdalar və axınlarla tanış ol, sonra kursda öyrəndiklərini birləşdirərək şagird jurnalı proqramı qur.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Sadə verilənlər sinfini record ilə yazmaq və var-dan yerində istifadə etmək
  • Lambda ifadələri və metod istinadları yazmaq
  • Axınlarla (filter, map, sorted) kolleksiyaları emal etmək və hamısını bir layihədə birləşdirmək

Java 30 yaşını keçib, amma köhnəlməyib: son illərdə dilə kodu xeyli qısaldan imkanlar əlavə olunub. Əvvəllər 40 sətir tələb edən sinif indi bir sətirlik record-a çevrilir, beş sətirlik dövr isə bir sətirlik axına. Bu dərsdə bu imkanlarla tanış olacaq, sonra isə kurs boyu öyrəndiklərini birləşdirib kiçik, amma real layihə — şagird jurnalı quracaqsan.

record və var

Record (Java 16-dan) dəyişməz verilənləri saxlayan sinfin qısa yazılışıdır. record Point(int x, int y) yazanda Java özü private final sahələri, konstruktoru, x() və y() metodlarını, həmçinin equals, hashCode və toString metodlarını yaradır. Record-a öz metodlarını da əlavə etmək olar. var isə lokal dəyişənin tipini kompilyatorun özünə təyin etməyə imkan verir.

Java
public class Main {
    public static void main(String[] args) {
        Point a = new Point(3, 4);
        Point b = new Point(3, 4);
        System.out.println(a);
        System.out.println(a.x() + a.y());
        System.out.println(a.equals(b) + " " + (a == b));
        System.out.println(a.distanceToOrigin());
        var message = "Records save time";
        var count = message.length();
        System.out.println(message + " (" + count + " chars)");
    }
}

record Point(int x, int y) {
    double distanceToOrigin() {
        return Math.sqrt(x * x + y * y);
    }
}
Gözlənilən nəticə
Point[x=3, y=4]
7
true false
5.0
Records save time (17 chars)

a.equals(b) true verdi: record-lar məzmuna görə müqayisə olunur. a == b isə false-dur, çünki bunlar iki ayrı obyektdir. Getter-lərin adında get yoxdur: getX() deyil, sadəcə x().

Lambdalar və metod istinadları

Lambda ifadəsi adsız qısa funksiyadır: n -> n * n — «n al, n * n qaytar». Lambdalar funksional interfeyslərin — yalnız bir abstrakt metodu olan interfeyslərin yerinə işlədilir: Predicate (şərti yoxlayır), Function (qiyməti çevirir), Comparator (iki obyekti müqayisə edir). Lambda yalnız hazır metodu çağırırsa, onu metod istinadı ilə daha qısa yazmaq olar: System.out::println.

Java
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

public class Main {
    public static void main(String[] args) {
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Function<Integer, Integer> square = n -> n * n;
        System.out.println(isEven.test(4) + " " + square.apply(7));

        List<String> names = new ArrayList<>(List.of("Murad", "Aysel", "Elvin", "Leyla"));
        names.sort((a, b) -> a.compareTo(b));
        names.removeIf(name -> name.startsWith("E"));
        names.forEach(name -> System.out.print(name + " "));
        System.out.println();
        names.forEach(System.out::println);
    }
}
Gözlənilən nəticə
true 49
Aysel Leyla Murad 
Aysel
Leyla
Murad

Axınlar (Stream API)

Axın (stream) kolleksiyanın elementlərini konveyer kimi emal edir: filter şərtə uyğun olanları saxlayır, map hər elementi çevirir, sorted sıralayır, toList, count, sum və ya average isə nəticəni toplayır. Axın mənbə kolleksiyanı dəyişmir. Kod «necə etməli» deyil, «nə etməli» sualına cavab verir, ona görə asan oxunur.

Java
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> scores = List.of(78, 95, 62, 88, 45, 91);
        List<Integer> passed = scores.stream()
                .filter(s -> s >= 60)
                .sorted()
                .toList();
        System.out.println(passed);
        int total = scores.stream().mapToInt(Integer::intValue).sum();
        double avg = scores.stream().mapToInt(Integer::intValue).average().orElse(0);
        System.out.println(total + " " + avg);
        String initials = List.of("Baku", "Ganja", "Shaki").stream()
                .map(c -> c.substring(0, 1))
                .collect(Collectors.joining("-"));
        System.out.println(initials);
        long count = scores.stream().filter(s -> s > 80).count();
        System.out.println(count);
    }
}
Gözlənilən nəticə
[62, 78, 88, 91, 95]
459 76.5
B-G-S
3

Layihə: şagird jurnalı

  1. 1
    Verilənləri modelləşdir

    Şagird — adı və qiymətlər siyahısı olan record. Onun kompakt konstruktoru 0–100 aralığından kənar balları IllegalArgumentException ilə rədd edir.

  2. 2
    Hesablamaları əlavə et

    average() axınla orta balı tapır və onu bir onluq rəqəmə yuvarlaqlaşdırır, letter() isə switch ifadəsi ilə hərf qiyməti verir.

  3. 3
    Jurnal sinfini yaz

    GradeBook şagirdləri private ArrayList-də saxlayır, sıralanmış hesabatı çap edir və sinfin orta balını hesablayır.

  4. 4
    Hamısını main-də birləşdir

    Şagirdləri əlavə et, səhv məlumatı try/catch ilə tut və hesabatı çap et.

Java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        GradeBook book = new GradeBook();
        book.add(new Student("Aysel", List.of(92, 88, 95)));
        book.add(new Student("Murad", List.of(85, 78, 84)));
        book.add(new Student("Leyla", List.of(58, 49, 61)));
        book.add(new Student("Nigar", List.of(70, 65, 72)));
        try {
            book.add(new Student("Elvin", List.of(90, 120)));
        } catch (IllegalArgumentException e) {
            System.out.println("Skipped: " + e.getMessage());
        }
        book.printReport();
        System.out.println("Class average: " + book.classAverage());
    }
}

record Student(String name, List<Integer> scores) {
    Student {
        for (int s : scores) {
            if (s < 0 || s > 100) throw new IllegalArgumentException(name + " has score " + s);
        }
    }

    double average() {
        double avg = scores.stream().mapToInt(Integer::intValue).average().orElse(0);
        return Math.round(avg * 10) / 10.0;
    }

    String letter() {
        return switch ((int) average() / 10) {
            case 10, 9 -> "A";
            case 8 -> "B";
            case 7 -> "C";
            case 6 -> "D";
            default -> "F";
        };
    }
}

class GradeBook {
    private final List<Student> students = new ArrayList<>();

    void add(Student s) { students.add(s); }

    double classAverage() {
        double avg = students.stream().mapToDouble(Student::average).average().orElse(0);
        return Math.round(avg * 10) / 10.0;
    }

    void printReport() {
        students.stream()
                .sorted(Comparator.comparingDouble(Student::average).reversed())
                .forEach(s -> System.out.println(s.name() + ": " + s.average() + " (" + s.letter() + ")"));
    }
}
Gözlənilən nəticə
Skipped: Elvin has score 120
Aysel: 91.7 (A)
Murad: 82.3 (B)
Nigar: 69.0 (D)
Leyla: 56.0 (F)
Class average: 74.8
Bütün layihə bir faylda — Main.java
LayihədəHansı mövzudan
record Student, Student { ... }record-lar, konstruktorlar
throw new IllegalArgumentException, try/catchistisnalar
switch ((int) average() / 10)switch ifadələri, tiplərin çevrilməsi
private final List<Student>inkapsulyasiya, kolleksiyalar, generiklər
stream(), Student::average, s -> ...axınlar, metod istinadları, lambdalar

Student { ... } — record-un kompakt konstruktorudur: parametrləri yenidən yazmadan yoxlama aparmağa imkan verir, sahələr isə sonra avtomatik doldurulur. Elvinin 120 balı qəbul olunmadı və o, jurnala düşmədi, amma proqram işini davam etdirdi — istisnalar dərsindəki kimi.

Əsas fikirlər

  • record dəyişməz verilənlər sinfini bir sətirdə yaradır: sahələr, konstruktor, getter-lər, equals və toString avtomatikdir.
  • var lokal dəyişənin tipini kompilyatora təyin etdirir, amma tip yenə də dəyişməzdir.
  • Lambda (x -> ...) funksional interfeysin qısa reallaşdırılmasıdır; Tip::metod isə metod istinadıdır.
  • Axın: stream() → filter / map / sorted → toList, count, sum, average; mənbə kolleksiya dəyişmir.
  • Real layihə kursun bütün hissələrini birləşdirir: siniflər, istisnalar, kolleksiyalar və müasir Java.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
record Point(int x, int y) üçün x koordinatını necə oxumaq olar?