CodeGym /Kurslar /JAVA 25 SELF /Yeni kolleksiyalar: SequencedCollection, SequencedSet, Se...

Yeni kolleksiyalar: SequencedCollection, SequencedSet, SequencedMap

JAVA 25 SELF
Səviyyə , Dərs
Mövcuddur

1. Klassik kolleksiyalarda sıra problemi

Java-da həmişə elementlərin ardıcıllığını təmin edən kolleksiyalar (məsələn, ArrayList, LinkedList, LinkedHashSet, LinkedHashMap) və ardıcıllıq təmin etməyənlər (məsələn, HashSet, HashMap) mövcud olub. Lakin bu kolleksiyaların hamısının bir ümumi çatışmazlığı var idi: bəziləri elementləri müəyyən qaydada saxlasalar da, standart interfeyslər (List, Set, Map) birinci və sonuncu elementlərə çıxış üçün və ya ardıcıllığı tərsinə çevirmək üçün universal metodlar təqdim etmirdi.

Məsələn, əgər sizdə List<String> varsa, birinci elementi list.get(0) ilə götürə bilərsiniz, lakin Set və ya Map üçün bu fənd işləməyəcək — ya iteratorlardan istifadə etməli, ya da əlavə kod yazmalı olacaqsınız. Razılaşın, bu nə çox rahatdır, nə də oxunaqlılığı artırır.

Bu elədir ki, sanki sizdə siyirtməli bir şkaf var, amma hər dəfə birinci və ya sonuncu siyirtməni çıxarmaq üçün bütün siyirtmələri əl ilə saymalı olursunuz! “Birinci” və “sonuncu” üçün xüsusi dəstəklər olsaydı, əla olmazdımı?

SequencedCollection və əlaqəli interfeyslərin yaradılması

Java 21-də yeni kolleksiya interfeysləri təqdim edildi:

  • SequencedCollection<E>
  • SequencedSet<E>
  • SequencedMap<K, V>

Bu interfeyslər standart kolleksiyaları genişləndirir və elementlərin ardıcıllığı ilə işləməyə vahid yanaşma gətirir. İndi ardıcıllığın vacib olduğu hər hansı kolleksiyalar üçün, konkret reallaşdırma haqqında düşünmədən universal kod yaza bilərsiniz.

Bu nədir?

  • SequencedCollection — elementlərin müəyyən qaydada olduğu və birinci, sonuncu elementi asanlıqla əldə etmək, həmçinin ardıcıllığı tərsinə çevirmək imkanı olan kolleksiyadır.
  • SequencedSet — eyni yanaşma, lakin çoxluqlar (unikal elementlər) üçün.
  • SequencedMap — eyni yanaşma, lakin xəritələr (açar-dəyər) üçün.

İndi bunları hansı kolleksiyalar reallaşdırır?

Java 21-də yeni interfeysləri aşağıdakı standart kolleksiyalar reallaşdırır:

  • ArrayList, LinkedListSequencedCollection
  • LinkedHashSet, TreeSetSequencedSet
  • LinkedHashMap, TreeMapSequencedMap

Bu o deməkdir ki, əgər siz artıq bu kolleksiyalardan istifadə edirsinizsə, avtomatik olaraq yeni imkanlar əldə edirsiniz!

2. SequencedCollection, SequencedSet, SequencedMap üçün əsas metodlar

Metodlar: SequencedCollection

E getFirst();      // Birinci elementi əldə et
E getLast();       // Son elementi əldə et
SequencedCollection<E> reversed(); // Kolleksiyanı tərsinə qaydada təqdim et

Metodlar: SequencedSet

SequencedCollection üçün olan eyni metodlar, üstəlik Setin təqdim etdikləri.

Metodlar: SequencedMap

Map.Entry<K, V> firstEntry();    // Birinci element (açar-dəyər)
Map.Entry<K, V> lastEntry();     // Son element (açar-dəyər)
SequencedMap<K, V> reversed();   // Xəritə əks ardıcıllıqla

3. Yeni interfeyslərin istifadəsinə nümunələr

Nümunə 1: Birinci və sonuncu elementin alınması

import java.util.*;

public class SequencedDemo {
    public static void main(String[] args) {
        SequencedCollection<String> sc = new ArrayList<>();
        sc.add("Java");
        sc.add("Python");
        sc.add("Kotlin");

        // Birinci və sonuncu elementi əldə et
        String first = sc.getFirst(); // "Java"
        String last = sc.getLast();   // "Kotlin"

        System.out.println("Birinci: " + first);
        System.out.println("Sonuncu: " + last);
    }
}

Nəticə:

Birinci: Java
Sonuncu: Kotlin

Nümunə 2: Kolleksiyanı tərsinə çevirmək

SequencedCollection<String> sc = new LinkedList<>();
sc.add("A");
sc.add("B");
sc.add("C");

SequencedCollection<String> reversed = sc.reversed();
System.out.println(reversed); // [C, B, A]

Nəzərə alın: reversed() kolleksiyanın əks ardıcıllıqda təqdimatını qaytarır. Əgər ilkin kolleksiyanı dəyişsəniz, reversed təqdimatı da dəyişəcək!

Nümunə 3: SequencedSet ilə işləmək

SequencedSet<Integer> set = new LinkedHashSet<>();
set.add(100);
set.add(200);
set.add(300);

System.out.println("Birinci element: " + set.getFirst()); // 100
System.out.println("Son element: " + set.getLast()); // 300

SequencedSet<Integer> reversedSet = set.reversed();
System.out.println(reversedSet); // [300, 200, 100]

Nümunə 4: SequencedMap ilə işləmək

SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.put("apple", 5);
map.put("banana", 3);
map.put("cherry", 7);

Map.Entry<String, Integer> first = map.firstEntry();
Map.Entry<String, Integer> last = map.lastEntry();

System.out.println("Birinci: " + first.getKey() + " = " + first.getValue()); // apple = 5
System.out.println("Sonuncu: " + last.getKey() + " = " + last.getValue()); // cherry = 7

SequencedMap<String, Integer> reversedMap = map.reversed();
System.out.println(reversedMap); // {cherry=7, banana=3, apple=5}

4. Bu, sizin tətbiqinizlə necə bağlıdır?

Tutaq ki, tədris tətbiqinizdə sistemə daxil olan istifadəçilərin siyahısını saxlayırsınız və birinci və sonuncu istifadəçini tez əldə etmək istəyirsiniz (məsələn, “kim ilk daxil oldu” və “kim ən sonda”). Əvvəllər belə bir şey yazmalı olurdunuz:

List<String> users = new ArrayList<>();
// ... istifadəçiləri əlavə edirik
String first = users.get(0);
String last = users.get(users.size() - 1);

Amma kolleksiya siyahı yox, məsələn, LinkedHashSetdirsə (elementlər unikaldır və sıra saxlanılır), bu fənd işləməyəcək:

Set<String> users = new LinkedHashSet<>();
// ... istifadəçiləri əlavə edirik
// Birincini necə əldə etməli? Yalnız iterator vasitəsilə:
String first = users.iterator().next();
// Bəs sonuncunu? Yalnız bütün elementləri keçməklə!

İndi isə hər şey daha sadə və universaldır:

SequencedSet<String> users = new LinkedHashSet<>();
// ... istifadəçiləri əlavə edirik
String first = users.getFirst();
String last = users.getLast();

Bu, təkcə kodun miqdarını azaltmır, həm də onu daha oxunaqlı və təhlükəsiz edir.

5. Yeni interfeyslərin sxemi

classDiagram
    Collection <|-- SequencedCollection
    List <|-- SequencedCollection
    Set <|-- SequencedSet
    Map <|-- SequencedMap
    SequencedCollection <|-- SequencedSet
    SequencedSet <|-- LinkedHashSet
    SequencedSet <|-- TreeSet
    SequencedCollection <|-- ArrayList
    SequencedCollection <|-- LinkedList
    SequencedMap <|-- LinkedHashMap
    SequencedMap <|-- TreeMap

6. Faydalı nüanslar

SequencedCollection-un praktiki üstünlükləri

  • Sıra ilə iş üçün vahid interfeys: Artıq harada get(0) olduğunu, harada iterator lazım gəldiyini və harada ümumiyyətlə birinci elementi almağın mümkün olmadığını yadda saxlamağa ehtiyac yoxdur.
  • Növbələr və yığınlarla işləyərkən rahatlıq: Asanlıqla birinci (head) və son (tail) elementi əldə etmək mümkündür.
  • Təhlükəsizlik və oxunaqlılıq: Kolleksiyalardan səhv istifadə ilə bağlı xətalar azalır; kod özünü izah edən olur.
  • Kolleksiyanın sürətlə tərsinə çevrilməsi: reversed() metodu əl işi olmadan əks ardıcıllığı asanlıqla əldə etməyə imkan verir.
  • Kodu saxlamaq və genişləndirmək asanlığı: Gələcəkdə məsələn, ArrayListi LinkedHashSet ilə əvəz etmək istəsəniz, SequencedCollection-dan istifadə edən kodu yenidən yazmağa ehtiyac qalmayacaq.

Reallaşdırma xüsusiyyətləri

  • Bütün kolleksiyalar SequencedCollection-u reallaşdırmır: Məsələn, HashSetHashMap ardıcıllığı təmin etmir, buna görə də yeni interfeysləri reallaşdırmır.
  • Metodlar istisna ata bilər: Kolleksiya boşdursa, getFirst() və ya getLast() çağırışı NoSuchElementException atacaq. Kolleksiyanın boş olmadığını yoxlamağı unutmayın!
  • reversed() — təqdimatdır, surət deyil: İlkin kolleksiyadakı dəyişikliklər tərsinə təqdimatda, tərsinə təqdimatda edilən dəyişikliklər isə ilkin kolleksiyada əks olunur.
  • Uyğunluq: Yeni interfeyslər yalnız Java 21-dən başlayaraq əlçatandır. Əgər daha köhnə Java versiyasından istifadə edirsinizsə, hələlik bu imkanlar sizə uyğun deyil (amma bu, yenilənmək üçün əla səbəbdir!).
  • Generics: Bütün yeni interfeyslər generics-i tam dəstəkləyir, beləliklə istənilən məlumat tipləri ilə işləmək mümkündür.

7. SequencedCollection ilə işləyərkən tipik səhvlər

Səhv №1: Ardıcıllıq təmin etməyən kolleksiyalardan ardıcıllıq gözləmək. Əgər siz HashSet-i SequencedSet-ə çevirməyə çalışsanız, kompilyasiya xətası alacaqsınız — HashSet ardıcıllığı təmin etmir və bu interfeysi reallaşdırmır.

Səhv №2: Boş kolleksiyaları nəzərə almamaq. Boş kolleksiyada getFirst() və ya getLast() çağırışı istisna atacaq. Bu metodlara müraciət etməzdən əvvəl kolleksiyanın boş olmadığını yoxlayın:

if (!sc.isEmpty()) {
    String first = sc.getFirst();
}

Səhv №3: reversed() ilə bağlı anlaşılmazlıqlar. reversed() metodu surəti deyil, təqdimatı qaytarır. Əgər reversed təqdimatını dəyişsəniz, ilkin kolleksiya da dəyişəcək (və əksinə). Bu davranışı gözləmirsinizsə, gözlənilməz nəticələrə səbəb ola bilər.

Səhv №4: Yeni interfeyslərdən Java-nın köhnə versiyalarında istifadə. Layihəniz Java 21-dən aşağı versiya ilə kompilyasiya olunursa, kompilyator bu interfeysləri tapmayacaq. Layihə ayarlarında JDK versiyasını yoxlayın!

1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Ağıllı tapşırıq idarəçisi: işləmədən əvvəl boşluğu yoxlamaq 🤖
Ağıllı tapşırıq idarəçisi: işləmədən əvvəl boşluğu yoxlamaq 🤖
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Addım algoritmi: birbaşa və tərs idarəetmə 🔄
Addım algoritmi: birbaşa və tərs idarəetmə 🔄
1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Müasir kolleksiyalar
Müasir kolleksiyalar və dəyişməzlik
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION