- Sadə verilənlər sinfini
recordilə 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.
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);
}
}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.
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);
}
}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.
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);
}
}[62, 78, 88, 91, 95] 459 76.5 B-G-S 3
Layihə: şagird jurnalı
- 1Verilənləri modelləşdir
Şagird — adı və qiymətlər siyahısı olan
record. Onun kompakt konstruktoru 0–100 aralığından kənar ballarıIllegalArgumentExceptionilə rədd edir. - 2Hesablamaları ə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. - 3Jurnal sinfini yaz
GradeBookşagirdləriprivateArrayList-də saxlayır, sıralanmış hesabatı çap edir və sinfin orta balını hesablayır. - 4Hamısını main-də birləşdir
Şagirdləri əlavə et, səhv məlumatı
try/catchilə tut və hesabatı çap et.
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() + ")"));
}
}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
| Layihədə | Hansı mövzudan |
|---|---|
record Student, Student { ... } | record-lar, konstruktorlar |
throw new IllegalArgumentException, try/catch | istisnalar |
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
recorddəyişməz verilənlər sinfini bir sətirdə yaradır: sahələr, konstruktor, getter-lər,equalsvətoStringavtomatikdir.varlokal 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::metodisə 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.
record Point(int x, int y) üçün x koordinatını necə oxumaq olar?