JavaRush /Java blogi /Random-UZ /Java 8 da looplardan xalos bo'lish
KapChook
Daraja
Volga

Java 8 da looplardan xalos bo'lish

Guruhda nashr etilgan
Java 8-da taqdim etilgan funktsional uslub tilga ajoyib qo'shimcha hisoblanadi. Endi Java sof OOP emas, endi u OOP va funktsional dasturlashning gibrididir. Bu o'yinni o'zgartiruvchi va biz ushbu o'zgarishlarni o'zlashtirish uchun OOP miyamizni o'zgartirishimiz kerak. Java 8 - 1 da looplardan xalos bo'lishLekin nega biz bu o'zgarishlarni qabul qilishimiz kerak? Muammoni sof OOP yordamida hal qila olsak, nega biz funktsional uslub bilan kelishishga vaqt sarflashimiz kerak?
  • Java 8-da taqdim etilgan funktsional uslub bizga biznes mantig'i va kod o'rtasidagi bo'shliqni kamaytirishga yordam beradi. Bu bizga hikoyani tabiiy oqimda yuqori darajada aytib berishga imkon beradi. Buni qanday qilishni xohlayotganingizni aytish o'rniga, nima qilishni xohlayotganingizni aytishingiz mumkin.

  • Kod yanada toza va ixchamroq bo'ladi.

  • Yuqori tartibli funktsiyalar bizga quyidagilarga imkon beradi:

    • Funksiyalarni boshqa funksiyalarga yuborish
    • Boshqa funksiyalar ichida funksiyalar yarating
    • Boshqa funksiyalardan funksiyalarni qaytarish

    Bu Java uchun katta yutuq, buning uchun ob'ektlarni yuborishimiz, yaratishimiz va qaytarishimiz kerak. Biz ishonchliroq, yo'naltirilgan va qayta ishlatish uchun qulayroq kod yozish imkoniyatiga ega bo'lamiz.

  • Lambdalar tufayli biz dangasa hisob-kitoblarni amalga oshirishimiz mumkin. Lambda ifodasi usul argumenti sifatida yuborilganda, kompilyator uni usulda chaqirilganda baholaydi. Bu oddiy usul argumentlaridan farq qiladi, ular darhol baholanadi.

  • Lambdalar yozish birligi testlarini qiziqarli qiladi. Ular bizga toza, kichik o'lchamli va tez yoziladigan engil testlarni yaratishga imkon beradi. Biz lambdalar yordamida sinov ostidagi kodni yo'q qilishimiz mumkin. Bu bizga barcha turdagi stsenariylar kodga qanday ta'sir qilishini sinab ko'rish imkonini beradi.

  • O'rganish uchun yangi naqshlar.

  • Va boshqalar!

Lekin etarli suv, ushbu maqolada biz an'anaviy tsikllarga muqobil echimlarni ko'rib chiqamiz. Albatta, tsikllar moslashuvchan, ammo bu narxsiz kelmaydi. break, tsiklning xatti-harakatlarini keskin o'zgartirib, bizni nafaqat kod nimaga erishmoqchi ekanligini tushunishga, continuebalki returntsikl qanday ishlashini tushunishga ham majbur qiladi. Endi biz tsikllarni qanday qilib qisqaroq va o'qilishi mumkin bo'lgan kodga aylantirishimiz mumkinligini ko'rib chiqamiz.

Kodlashni boshlaylik!

Biz maqolalar bilan ishlaymiz. Maqolada sarlavha, muallif va bir nechta teglar mavjud.
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;
    }
}
Har bir misol halqalar yordamida anʼanaviy yechim va Java 8 ning yangi funksiyalaridan foydalangan holda yechimni oʻz ichiga oladi. Birinchi misolda biz “Java” tegi bilan toʻplamdagi birinchi maqolani topmoqchimiz. Keling, halqa yordamida yechimni ko'rib chiqaylik.
public Article getFirstJavaArticle() {

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            return article;
        }
    }
    return null;
}
Endi Stream API dan operatsiyalar yordamida muammoni hal qilaylik.
public Optional<Article> getFirstJavaArticle() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .findFirst();
    }
Juda zo'r, shunday emasmi? filterBiz birinchi navbatda “Java” yorlig'i bilan barcha maqolalarni topish uchun operatsiyadan foydalanamiz , keyin biz findFirst()birinchi hodisani olish uchun foydalanamiz. Oqimlar dangasa va filtr oqimni qaytarganligi sababli, bu yondashuv faqat birinchi moslikni topmaguncha elementlarni qayta ishlaydi. Keling, birinchi maqola o'rniga "Java" tegi ostidagi barcha maqolalarni olaylik. Avval halqalar yordamida yechim.
public List<Article> getAllJavaArticles() {

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

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            result.add(article);
        }
    }
    return result;
}
Oqim operatsiyalari yordamida yechim.
public List<Article> getAllJavaArticles() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());
    }
Ushbu misolda biz collectto'plamni e'lon qilish va mos keladigan yozuvlarni aniq qo'shish o'rniga, natijada paydo bo'lgan oqimni qisqartirish uchun operatsiyadan foydalandik. Hozirgacha juda yaxshi. Stream API-ni chindan ham yorqin qiladigan misollar vaqti. Keling, barcha maqolalarni muallif bo'yicha guruhlaymiz. Odatdagidek, biz uni halqalar yordamida hal qilishni boshlaymiz:
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;
}
Oqim operatsiyalari yordamida ushbu muammoga toza yechim topa olamizmi?
public Map<String, List<Article>> groupByAuthor() {
    return articles.stream()
        .collect(Collectors.groupingBy(Article::getAuthor));
}
Ajoyib! Amaliyot groupingByva usul havolasidan foydalanib getAuthor(), biz toza va o'qilishi mumkin bo'lgan kodni olamiz. Endi to'plamda ishlatiladigan teglarning qolgan qismini topamiz. Keling, tsikl misolidan boshlaylik:
public Set<String> getDistinctTags() {

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

    for (Article article : articles) {
        result.addAll(article.getTags());
    }
    return result;
}
OK, keling, oqim operatsiyalari yordamida buni qanday hal qilish mumkinligini ko'rib chiqamiz:
public Set<String> getDistinctTags() {
    return articles.stream()
        .flatMap(article -> article.getTags().stream())
        .collect(Collectors.toSet());
}
Ajoyib! flatmapteglar ro'yxatini bitta natija oqimiga tekislashimizga yordam beradi, biz undan keyin collectqaytish to'plamini yaratish uchun foydalanamiz.

Cheksiz Imkoniyatlar

Bu looplarni qanday qilib o'qilishi mumkin bo'lgan kod bilan almashtirish mumkinligiga 4 ta misol edi. Stream API-ni tekshirib ko'ring, chunki bu maqola faqat sirtni tirnalgan. Java-ning yangi funktsional uslubini o'zlashtirish OOP ishlab chiquvchilari uchun qiyin bo'ladi, ammo bu yaxshi qabul qilinishi kerak bo'lgan qiyinchilik. Men hatto oldinga boraman va sof funktsional dasturlash tilini o'rganishingiz kerakligini aytaman. Shunday qilib, siz u taqdim etadigan imkoniyatlar va quvvatni to'liq tushunishingiz mumkin. O'ylaymanki, bu sizga funktsional dasturlashni boshqa darajada tushunishga yordam beradi. Shunday qilib, eski yaxshi OOP bilan birga funktsional dasturlashni o'rganing va ikkalasidan ham kattaroq kod yozish uchun foydalaning! Ikkita maqola tarjimalarining bepul aralashmasi - Nima uchun Java 8 da funktsional dasturlashni va Java 8 da Swerving Away from Loops ni qabul qilishingiz kerak
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION