CodeGym /Kurslar /JAVA 25 SELF /Kolleksiya elementlərinin filtrlənməsi

Kolleksiya elementlərinin filtrlənməsi

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

1. Giriş

Proqramlaşdırmada tez-tez böyük bir məlumat toplusundan yalnız lazım olan elementləri seçmək lazım gəlir — buna filtrləmə deyilir. Yalnız cüt ədədləri saxlamaq, "Java" sözünü ehtiva edən sətirləri tapmaq və ya 18 yaşdan yuxarı istifadəçiləri seçmək — bunların hamısı filtrləmə tapşırıqlarıdır.

Java-da bu cür əməliyyatlar hər addımda rast gəlinir, buna görə onları yerinə yetirməyin müxtəlif yollarına əminliklə yiyələnmək və xüsusiyyətlərini anlamaq vacibdir.

2. Dövr vasitəsilə filtrləmə

Ən əsas üsuldan başlayaq — adi for dövrəsi. Bu yanaşmaya imperativ deyilir, çünki siz açıq şəkildə nəyi və necə etmək lazım olduğunu göstərirsiniz. Oxunması rahatdır və anlamaq asandır.

Nümunə: yalnız cüt ədədləri saxlamaq

import java.util.*;

public class FilterExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        List<Integer> evenNumbers = new ArrayList<>(); // Nəticə üçün yeni siyahı yaradırıq

        for (Integer n : numbers) {
            if (n % 2 == 0) { // Şərti yoxlayırıq: cüt ədəd
                evenNumbers.add(n);
            }
        }

        System.out.println("Cüt ədədlər: " + evenNumbers);
    }
}

Nəticə:

Cüt ədədlər: [2, 4, 6, 8, 10]

Burada vacib məqam: ilkin kolleksiya (numbers) dəyişmir. Nəticəni yeni bir siyahıda toplayırıq.

Nümunə: sətirlərin alt sətirə görə filtrlənməsi

List<String> words = Arrays.asList("java", "python", "javascript", "kotlin", "c++");
List<String> javaWords = new ArrayList<>();

for (String word : words) {
    if (word.contains("java")) {
        javaWords.add(word);
    }
}
System.out.println(javaWords); // [java, javascript]

Eyni prinsip: sətirlər siyahısını gəzib contains metodu ilə alt sətirin olub-olmadığını yoxlayırıq.

3. Kolleksiyadan elementlərin silinməsi: niyə hər şey bu qədər sadə deyil?

Harada tələ var?

Bəzən silərək ilkin kolleksiyadan bütün lazımsız elementləri çıxarmaq istəyirik. Lakin for-each dövründə bunu etməyə cəhd etsəniz, ConcurrentModificationException istisnası alacaqsınız.

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));

for (Integer n : numbers) {
    if (n < 0) {
        numbers.remove(n); // TƏHLÜKƏLİ! ConcurrentModificationException!
    }
}

Nəticə:

Exception in thread "main" java.util.ConcurrentModificationException

Belə keçid zamanı kolleksiyalar onları modifikasiya etməyi “sevmir” — iterasiya pozulur.

Elementləri kolleksiyadan düzgün necə silmək olar?

Yol 1: Iterator.remove() istifadə etmək

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));

Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
    Integer n = it.next();
    if (n < 0) {
        it.remove(); // Təhlükəsiz şəkildə silirik!
    }
}
System.out.println(numbers); // [1, 3, 5]

Burada iterator() metodu ilə iterator yaradırıq, kolleksiya boyunca hasNext()next() ilə hərəkət edirik, lazımsız elementləri isə it.remove() çağırışı ilə silirik.

Yol 2: yalnız lazım olan elementlərlə yeni siyahı yaratmaq

List<Integer> numbers = Arrays.asList(1, -2, 3, -4, 5);
List<Integer> positive = new ArrayList<>();

for (Integer n : numbers) {
    if (n >= 0) {
        positive.add(n);
    }
}
System.out.println(positive); // [1, 3, 5]

İlkin kolleksiyaya toxunmur və yeni siyahı yaradırıq. Yanaşma təhlükəsizdir, anlaşıqlıdır və şərtlər mürəkkəbləşdikdə asan genişlənir.

Yol 3: removeIf istifadə etmək (Java 8+)

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));
numbers.removeIf(n -> n < 0);
System.out.println(numbers); // [1, 3, 5]

Bir sətirlə şərti ötürürük: “sıfırdan kiçik olanların hamısını sil”. Təhlükəsiz modifikasiya ilə bağlı daxili detalları kolleksiya özü həll edir.

Nəticə: elementləri silmək üçün for-each istifadə etməyin. Iterator.remove(), yeni siyahı yaratmaq və ya yığcam removeIf arasında seçim edin.

4. Filtrləmə üçün hansı üsulu nə zaman istifadə etməli?

Imperativ yanaşma — adi dövr vasitəsilə — sizə təkcə elementləri seçmək yox, həm də onlarla dərhal nəsə etmək lazım olanda (məsələn, çıxışa vermək və ya çevirmək) rahatdır. Sadə və şəffafdır.

Söhbət məhz silinmədən gedirsə, for-each daxilində silməkdən qaçın. Addım-addım nəzarət üçün Iterator.remove() istifadə edin və ya müasir removeIf() — mümkün qədər qısa və ifadəli üsuldur.

Nümunə: sözlərdən ibarət siyahı var, dörd simvoldan qısa olan bütün sözləri silmək lazımdır:

List<String> words = new ArrayList<>(Arrays.asList("Java", "is", "fun", "awesome", "code"));
words.removeIf(word -> word.length() < 4);
System.out.println(words); // [Java, awesome, code]

removeIf metodu predikat qəbul edir — filtrləmə qaydası — və ona uyğun olanların hamısını silir.

5. Kolleksiyaları filtrləyərkən tipik səhvlər

Səhv №1: elementləri kolleksiyadan for-each dövründə silməyə cəhd.
Belə kod ConcurrentModificationException ilə nəticələnəcək:

for (Integer n : numbers) {
    if (n < 0) {
        numbers.remove(n); // BUM! ConcurrentModificationException
    }
}

Düzgün variantlar: Iterator.remove() və ya removeIf istifadə edin.

Səhv №2: filtrləmə şərtinin səhv qurulması.
Yalnız mənfi ədədləri silmək lazımdır:

List<Integer> numbers = new ArrayList<>(Arrays.asList(-3, -1, 0, 2, 4));
numbers.removeIf(n -> n < 0);
System.out.println(numbers); // [0, 2, 4]

Amma səhvən “qeyri-müsbət” yazıb <= istifadə etsəniz, sıfır da yox olacaq:

numbers.removeIf(n -> n <= 0); // Nəticə: [2, 4] — sıfır səhvən silinib

Şərtlərin dəqiqliyinə diqqət edin: tək bir yanlış müqayisə nəticəni tamamilə dəyişir.

1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Agentlərin dosyesinin "mənfi" məlumatlardan təmizlənməsi 🕵️‍♀️
Agentlərin dosyesinin "mənfi" məlumatlardan təmizlənməsi 🕵️‍♀️
1
Tapşırıq
JAVA 25 SELF, səviyyə, dərs
Bağlanıb
Yeni ensiklopediya üçün heyvan adlarını çeşidləyirik 🦒
Yeni ensiklopediya üçün heyvan adlarını çeşidləyirik 🦒
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION