JavaRush /Java Blogu /Random-AZ /Java 8-də döngələrdən qurtulmaq
KapChook
Səviyyə
Volga

Java 8-də döngələrdən qurtulmaq

Qrupda dərc edilmişdir
Java 8-də təqdim edilən funksional üslub dilə əla əlavədir. İndi Java təmiz OOP deyil, indi OOP və funksional proqramlaşdırmanın hibrididir. Bu, oyun dəyişdiricisidir və biz bu dəyişiklikləri qəbul etmək üçün OOP beynimizi dəyişdirməliyik. Java 8 - 1-də döngələrdən qurtulmaqBəs niyə biz bu dəyişiklikləri qəbul etməliyik? Problemi təmiz OOP-dan istifadə etməklə həll edə bildiyimiz halda, niyə funksional üslubla yola getməyə vaxt sərf etməliyik?
  • Java 8-də təqdim edilən funksional üslub bizə biznes məntiqi və kod arasındakı boşluğu azaltmağa kömək edir. Bu, bizə hekayəni daha yüksək səviyyədə təbii axınla danışmağa imkan verir. Bunu necə etmək istədiyinizi söyləmək əvəzinə, nə etmək istədiyinizi söyləyə bilərsiniz.

  • Kod daha təmiz və daha qısa olur.

  • Yüksək səviyyəli funksiyalar bizə imkan verir:

    • Funksiyaları digər funksiyalara göndərin
    • Digər funksiyaların daxilində funksiyalar yaradın
    • Digər funksiyalardan funksiyaları qaytarın

    Bu, Java üçün böyük bir qələbədir, burada bunu etmək üçün obyektləri göndərməli, yaratmalı və qaytarmalıyıq. Biz daha etibarlı, diqqət mərkəzində olan və təkrar istifadəsi asan kod yaza biləcəyik.

  • Lambdalar sayəsində biz tənbəl hesablamalar apara bilirik. Lambda ifadəsi metod arqumenti kimi göndərildikdə, kompilyator onu metodda çağırdıqda qiymətləndirəcək. Bu, dərhal qiymətləndirilən adi metod arqumentlərindən fərqlidir.

  • Lambdalar yazı vahidi testlərini əyləncəli edir. Onlar bizə təmiz, kiçik ölçülü və tez yazan yüngül testlər yaratmağa imkan verir. Lambdalardan istifadə edərək sınaq altında olan kodu kökündən çıxara bilərik. Bu, hər cür ssenarinin koda necə təsir edəcəyini sınamağa imkan verir.

  • Öyrənmək üçün yeni nümunələr.

  • Və daha çox!

Ancaq kifayət qədər su, bu yazıda ənənəvi dövrlərə alternativ həlləri nəzərdən keçirəcəyik. Əlbəttə ki, dövrələr çevikdir, lakin bu qiymətsiz gəlmir. break, döngənin davranışını kəskin şəkildə dəyişdirərək, bizi yalnız kodun nəyə nail olmağa çalışdığını anlamağa deyil, continuehəm returndə döngənin necə işlədiyini anlamağa məcbur edir. İndi biz döngələri daha qısa və oxunaqlı koda necə çevirə biləcəyimizə nəzər salacağıq.

Kodlaşdırma başlasın!

Məqalələrlə işləyəcəyik. Məqalənin adı, müəllifi və bir neçə teq var.
private class Article {

    private final String title;
    private final String author;
    private final List<String> tags;

    private Article(String title, String author, List<String> tags) {
        this.title = title;
        this.author = author;
        this.tags = tags;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public List<String> getTags() {
        return tags;
    }
}
Hər bir nümunə döngələrdən istifadə edən ənənəvi həlli və Java 8-in yeni xüsusiyyətlərindən istifadə edən həlli ehtiva edir. Birinci misalda biz kolleksiyada “Java” teqi ilə ilk məqaləni tapmaq istəyirik. Döngədən istifadə edərək həll yoluna nəzər salaq.
public Article getFirstJavaArticle() {

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            return article;
        }
    }
    return null;
}
İndi Stream API-dən əməliyyatlardan istifadə edərək problemi həll edək.
public Optional<Article> getFirstJavaArticle() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .findFirst();
    }
Olduqca sərin, elə deyilmi? filterƏvvəlcə “Java” etiketi ilə bütün məqalələri tapmaq üçün əməliyyatdan istifadə edirik , sonra findFirst()ilk hadisəni əldə etmək üçün istifadə edirik. Axınlar tənbəl olduğundan və filtr axın qaytardığından, bu yanaşma ilk uyğunluğu tapana qədər yalnız elementləri emal edəcək. İndi gəlin birinci məqalənin əvəzinə “Java” etiketli bütün məqalələri əldə edək. Əvvəlcə döngələrdən istifadə edərək həll edin.
public List<Article> getAllJavaArticles() {

    List<Article> result = new ArrayList<>();

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            result.add(article);
        }
    }
    return result;
}
Axın əməliyyatlarından istifadə edərək həll.
public List<Article> getAllJavaArticles() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());
    }
Bu nümunədə collectkolleksiya elan etmək və uyğun gələn qeydləri açıq şəkildə əlavə etmək əvəzinə, nəticədə yaranan axını qısaltmaq üçün əməliyyatdan istifadə etdik. İndiyə qədər yaxşı. Stream API-ni həqiqətən parlaq edəcək nümunələrin vaxtıdır. Bütün məqalələri müəllifə görə qruplaşdıraq. Həmişə olduğu kimi, döngələrdən istifadə edərək həll etməyə başlayırıq:
public Map<String, List<Article>> groupByAuthor() {

    Map<String, List<Article>> result = new HashMap<>();

    for (Article article : articles) {
        if (result.containsKey(article.getAuthor())) {
            result.get(article.getAuthor()).add(article);
        } else {
            ArrayList<Article> articles = new ArrayList<>();
            articles.add(article);
            result.put(article.getAuthor(), articles);
        }
    }
    return result;
}
Axın əməliyyatlarından istifadə edərək bu problemin təmiz həllini tapa bilərikmi?
public Map<String, List<Article>> groupByAuthor() {
    return articles.stream()
        .collect(Collectors.groupingBy(Article::getAuthor));
}
Heyrətamiz! Əməliyyat groupingByvə metod istinadından istifadə etməklə getAuthor()təmiz və oxunaqlı kod əldə edirik. İndi kolleksiyada istifadə olunan etiketlərin qalan hissəsini tapaq. Döngə nümunəsi ilə başlayaq:
public Set<String> getDistinctTags() {

    Set<String> result = new HashSet<>();

    for (Article article : articles) {
        result.addAll(article.getTags());
    }
    return result;
}
Yaxşı, gəlin axın əməliyyatlarından istifadə edərək bunu necə həll edə biləcəyimizə nəzər salaq:
public Set<String> getDistinctTags() {
    return articles.stream()
        .flatMap(article -> article.getTags().stream())
        .collect(Collectors.toSet());
}
Əla! flatmapteqlərin siyahısını bir nəticə axınına düzəltməkdə bizə kömək edir, biz bundan sonra collectqaytarma dəstini yaratmaq üçün istifadə edirik.

Sonsuz İmkanlar

Bunlar döngələrin daha oxunaqlı kodla necə əvəz oluna biləcəyinə dair 4 nümunə idi. Stream API-ni yoxladığınızdan əmin olun, çünki bu məqalə yalnız səthi cızmışdır. Java-nın yeni funksional üslubunu mənimsəmək OOP tərtibatçıları üçün çətin olacaq, lakin bu, yaxşı qarşılanmalı olan bir problemdir. Mən hətta daha da irəli gedəcəyəm və deyəcəyəm ki, siz təmiz funksional proqramlaşdırma dilini öyrənməlisiniz. Bu yolla siz onun təmin etdiyi imkanları və gücü tam başa düşə bilərsiniz. Düşünürəm ki, bu, funksional proqramlaşdırmanı başqa səviyyədə başa düşməyə kömək edəcək. Beləliklə, köhnə yaxşı OOP ilə birlikdə funksional proqramlaşdırmanı öyrənin və daha böyük kod yazmaq üçün hər ikisindən istifadə edin! İki məqalənin pulsuz tərcüməsi - Java 8-də funksional proqramlaşdırmanı və Java 8-də döngələrdən uzaqlaşmağı niyə qəbul etməlisiniz?
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION