OCA Java imtahan mövzuları

Predicates

Öncəki məqalədə yazdığımız  nümunələrdə biz istədiyimiz şərtin doğruluğunu yoxlamaq üçün Checker funksional interface`nin test() metodundan istifadə edirdik:

public interface Checker {
    boolean test(Animal a);
}

Burada biz parametr olaraq ancaq Animal tipində obyekt göndərə və şərtlərimizi ancaq Animal classı üçün yoxlaya bilirdik. Tutaq ki, indi bizim Person tipində classımız var və eyni şərtləri həmin class üçün də yoxlamalıyıq. Bunun üçün biz Person tipində obyekt qəbul edən yeni abstract metod yaratmalıyıq. Ancaq funksional interface`də birdən artıq abstract metod yaratmaq mümkün olmadığından məcburuq yeni funksional interface yaradaq. Bu problemi aradan qaldırmaq üçün java özü bizi hazır functional interface`lər ilə təmin edir. Həmin functional interface`lər java.util.function paketində yerləşir və OCA imtahanı üçün bizə bunlardan yalnız Predicate interface`ni öyrənmək kifayət edir.

@FunctionalInterface    // optional
public interface Predicate<T> {
    boolean test(T t);
}

Predicate interface`nin bizim Checker interface`indən ancaq bir fərqi var, o da generics olmağıdır. İndi biz yeni metod yaratmadan Predicate interface`nin test() metoduna Animal, Person, və yaxud hər hansı istənilən referans tip göndərə bilərik. Əgər Predicate interface`inə hər hansı bir tip təyin edilməzsə, default olaraq Object qəbul edir.

İndi öncəki məqalədə yazdığımız TraditionalSearch classını heç bir functional interface yaratmadan Predicate interface`i vasitəsilə yenidən yazaq:

import java.util.*;
import java.util.function.*;

public class PredicateSearch {

    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<Animal>();
        animals.add(new Animal("fish", false, true));
        animals.add(new Animal("dog", true, true));

        print(animals, a -> a.canHop());
    }

    private static void print(List<Animal> animals, Predicate<Animal> checker) {
        for (Animal animal : animals) {
            if (checker.test(animal)) {
                System.out.print(animal + " ");
            }
        }
        System.out.println();
    }
}

Tam aydın olsun deyə daha bir nümunəyə baxaq. Bu nümunə https://dzone.com saytında rastıma çıxdı, lambdanın önəmini göstərmək baxımından daha faydalı gəldi mənə, ona görə qeyd etmək qərarına gəldim. Deməli sizin belə bir listiniz var:

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

Və sizdən bu listin bütün elementlərinin cəmini verən metod yazmağınız tələb olunur. Aşağıdakı kimi bir metod yazırsız:

public int sumAll(List<Integer> numbers) {
    int total = 0;
    for (int number : numbers) {
        total += number;
    }
    return total;
}

Səhəri gün listin cüt elementlərinin cəmi də tələb olunduğu deyilir. Və ağlınıza gələn ilk şey həmin metodu kopyalayıb, adını və içindəki şərti dəyişmək olur:

public int sumEven(List<Integer> numbers) {
    int total = 0;
    for (int number : numbers) {
        if (number % 2 == 0) {
            total += number;
        }
    }
    return total;
}

Növbəti gün isə listin 3-dən böyük olan elementlərinin cəmi lazımdır deyəndə artıq başa düşürsünüz ki, copy-paste üsulu bu işlər üçün uyğun deyil, sizə optimal bir yöntəm lazımdı. Bu zaman lambda bizim köməyimizə gəlir. Predicate interface`indən istifadə edərək metodu bircə dəfə yazırıq:

public int sumAppropriateElements(List<Integer> numbers, Predicate<Integer> p) {
    int total = 0;
    for (int number : numbers) {
        if (p.test(number)) {
            total += number;
        }
    }
    return total;
}

Və tələb olunan şərtə uyğun lambda ifadəsi göndərərək lazımı nəticəni alırıq:

sumAppropriateElements(numbers, n -> true);       // all
sumAppropriateElements(numbers, n -> n % 2 == 0); // only even
sumAppropriateElements(numbers, n -> n > 3);      // greater than 3

İmtahanda Predicate ilə əlaqəli bilməli olduğumuz növbəti mövzu removeIf() metodudur. Bu metod ArrayList ilə istifadə edilir və parametr olaraq Predicate qəbul edir. Bu metodun üstünlüyü nədir baxaq. Tutaq ki, bizim adlar listimiz var və biz istəyirik ki, “C” hərfi ilə başlamayan adlar bu listdən silinsin. Ənənəvi qayda ilə yanaşsaq biz bu listi dövrə salıb hər elementi bir-bir şərtlə yoxlayıb silə bilərik. removeIf() metodunun köməkliyi ilə isə bunu bir sətirdə etmək mümkündür:

List<String> names = new ArrayList<>();
names.add("Elnur");
names.add("Ceyhun");
names.add("Cavid");
names.add("Adil");
names.add("Hasil");
names.add("Odər");
System.out.println(names);        // [Elnur, Ceyhun, Cavid, Adil, Hasil, Odər]
names.removeIf(s -> s.toLowerCase().charAt(0) != 'c');
System.out.println(names);        // [Ceyhun, Cavid]

removeIf() metodu ilə bağlı daha bir nümunəyə baxaq:

public class Whizlabs {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(21);
        list.add(13);
        list.add(30);
        list.add(11);
        list.add(2);
        // insert here
        System.out.println(list);
    }
}

Bu nümunə Whizlabs test bankında rastıma çıxmışdı və soruşulur ki, “insert here” yazısının əvəzinə aşağıdakı bəndlərdən hansı əlavə edilməlidir ki, output [21, 13, 11] olsun?

a. list.removeIf(e > e%2 != 0);
b. list.removeIf(e -> e%2 != 0);
c. list.removeIf(e -> e%2 == 0);
d. list.remove(e -> e%2 == 0);
e. Heç biri

Mövzunu yaxşı başa düşdüyünüzdən əmin olmaq üçün cavabı özünüz tapmağa cəhd edin 🙂

Enthuware-də rastlaşdığım suallardan biri də mənim üçün yenilik olmuşdu, kitabda həmin məsələyə rast gəlməmişdim. Kod nümunəsi və sual belə idi:

public class TestClass {

    public static boolean checkList(List list, Predicate<List> p) {
        return p.test(list);
    }

    public static void main(String[] args) {
        boolean b = //WRITE CODE HERE       
        System.out.println(b);
    }
}

Qeyd olunan hissəyə aşağıdakı bəndlərdən hansılar əlavə edilərsə, output true olar?

a. checkList(new ArrayList(), al -> al.isEmpty());
b. checkList(new ArrayList(), ArrayList al -> al.isEmpty());
c. checkList(new ArrayList(), al -> return al.size() == 0);
d. checkList(new ArrayList(), al -> al.add("hello"));
e. checkList(new ArrayList(), (ArrayList al) -> al.isEmpty());

bc bəndlərində aşkar sintaksis səhvi olduğundan düzgün cavablar deyil, qalır a, de. add()isEmpty() metodları geri true qaytarır və sintaksis ilə hər şey qaydasında olduğuna görə ad düzgün cavablardır. Geriyə bircə e variantı qalır və mənim də ən çox diqqətimi çəkən bənd bu olmuşdu. Bu bənddə də hər şey qaydasında görünürdü, fikirləşirdim yəqin bu da düzgün cavab ola bilər, amma elə deyil, e səhv cavabdır. Çünki checkList metodunda Predicate-in tipi List göstərilib, e bəndində də al dəyişəninin tipi mütləq List olmalıdır, ArrayList ola bilməz. Buna diqqət etmək lazımdır.

Predicate interface`i ilə birbaşa hazır filterlər də yaratmaq mümkündir. Məsələn, sizə belə bir filter lazımdı: sözün tərkibində kiçik “a” hərfi olsun, amma söz kiçik “a” ilə başlamasın. Bu filteri aşağıdakı şəkildə yaza bilərik:

   Predicate<String> filter = s -> s.indexOf("a") > 0;

Sözün bu filterə uyğun gəlib-gəlmədiyini yoxlamaq üçün isə aşağıdakı kodu çağırmaq kifayətdir:

System.out.println(filter.test("java")); // true
System.out.println(filter.test("asp"));  // false

Mövzunun sonunda isə öz imtahan təcrübəmdən bir məqamı vurğulamaq istəyirəm. Deməli, mən imtahan verən zaman 1Z0-808 (digər adı ilə OCA SE 8) imtahanında 77 sual olurdu. Və mənə cəmi cümlətanı bircə lambda sualı düşmüşdü və həmin sualı da səhv cavablandırmışdım 🙂 İmtahandan çıxan kimi IDE-ni açıb birinci yoxladığım sual da elə bu sual idi və səhvin nədə olduğunu başa düşmüşdüm. Həqiqətən maraqlı sual idi, nə oxuduğum kitabda, nə də test banklarında bu tip sual ilə rastlaşmamışdım. Ola bilsin feedback`lər əsasında sonradan Enthuware test bankına əlavə etsinlər. Bu sual ilə bağlı ətraflı şəkildə blogda imtahan təcrübəm bölməsində qeyd etmişəm, kiməsə maraqlı olsa buradan baxa bilər.

 

[topics lang=az]

About the author

Mushfiq Mammadov

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.