-
Java 8де киргизилген функционалдык стиль бизнес логикасы менен codeдун ортосундагы ажырымды кыскартууга жардам берет. Бул бизге окуяны табигый агымда жогорку деңгээлде айтууга мүмкүндүк берет. Кандай кылгыңыз келгенин айтуунун ордуна, эмне кылгыңыз келгенин айта аласыз.
-
Код тазараак жана кыскараак болот.
-
Жогорку тартиптеги функциялар бизге:
- Функцияларды башка функцияларга жөнөтүү
- Башка функциялардын ичинде функцияларды түзүү
- Башка функциялардан функцияларды кайтаруу
Бул Java үчүн чоң утуш, бул үчүн an objectтерди жөнөтүү, түзүү жана кайтаруу керек. Биз ишенимдүү, багытталган жана кайра колдонууга оңой болгон codeду жаза алабыз.
-
Ламбдалардын жардамы менен биз жалкоо эсептөөлөрдү жасай алабыз. Ламбда туюнтмасы методдун аргументи катары жөнөтүлгөндө, компилятор аны методдо чакырганда баалайт. Бул дароо бааланган кадимки ыкма аргументтеринен айырмаланат.
-
Ламбдалар жазуу бирдигинин тесттерин кызыктуу кылат. Алар бизге таза, көлөмү кичинекей жана тез жазыла турган жеңил тесттерди түзүүгө мүмкүндүк берет. Биз lambdas аркылуу текшерorп жаткан codeду түп тамыры менен жок кыла алабыз. Бул ар кандай сценарийлердин codeго кандай таасир этээрин сынап көрүүгө мүмкүнчүлүк берет.
-
Жаңы үлгүлөрдү үйрөнүү.
-
Жана дагы көп нерселер!
break
, циклдин жүрүм-турумун кескин түрдө өзгөртүп, бизди code эмнеге жетүүгө аракет кылып жатканын түшүнүүгө гана эмес continue
, return
циклдин кантип иштээрин түшүнүүгө да мажбурлайт. Эми биз циклдерди кантип кыскараак жана окула турган codeго айландырса болорун карап чыгабыз.
Коддоштуруу башталсын!
Биз макалалар менен иштейбиз. Макаланын аталышы, автору жана бир нече теги бар.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;
}
}
Ар бир мисал илмектерди колдонуу менен салттуу чечимди жана Java 8дин жаңы мүмкүнчүлүктөрүн колдонуу менен чечимди камтыйт. Биринчи мисалда биз жыйнактагы биринчи макаланы “Java” теги менен тапкыбыз келет. Келгиле, циклди колдонуу менен чечимди карап көрөлү.
public Article getFirstJavaArticle() {
for (Article article : articles) {
if (article.getTags().contains("Java")) {
return article;
}
}
return null;
}
Эми Stream API'ден операцияларды колдонуу менен маселени чечели.
public Optional<Article> getFirstJavaArticle() {
return articles.stream()
.filter(article -> article.getTags().contains("Java"))
.findFirst();
}
Абдан сонун, туурабы? filter
Адегенде биз "Java" теги менен бардык макалаларды табуу үчүн операцияны колдонобуз , андан кийин биз findFirst()
биринчи көрүнүштү алуу үчүн колдонобуз. Агымдар жалкоо болгондуктан жана чыпка агымды кайтарып бергендиктен, бул ыкма элементтерди биринчи дал келгенди тапканга чейин гана иштетет. Эми биринчи эле макаланын ордуна "Java" деп белгиленген бардык макалаларды алалы. Алгач илмектерди колдонуп чечүү.
public List<Article> getAllJavaArticles() {
List<Article> result = new ArrayList<>();
for (Article article : articles) {
if (article.getTags().contains("Java")) {
result.add(article);
}
}
return result;
}
Агым операцияларын колдонуу менен чечим.
public List<Article> getAllJavaArticles() {
return articles.stream()
.filter(article -> article.getTags().contains("Java"))
.collect(Collectors.toList());
}
Бул мисалда биз collect
коллекцияны жарыялоонун жана дал келген жазууларды ачык кошуунун ордуна, натыйжадагы агымды кыскартуу операциясын колдондук. Азырынча жакшы. Stream API чындап жаркыраган мисалдар үчүн убакыт. Бардык макалаларды автор боюнча топтойлу. Адаттагыдай эле, биз циклдерди колдонуу менен чечүү менен баштайбыз:
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;
}
Агым операцияларын колдонуу менен бул көйгөйдүн таза жолун таба алабызбы?
public Map<String, List<Article>> groupByAuthor() {
return articles.stream()
.collect(Collectors.groupingBy(Article::getAuthor));
}
Укмуш! Операцияны groupingBy
жана метод шилтемесин колдонуу менен getAuthor()
биз таза жана окула турган codeду алабыз. Эми коллекцияда колдонулган тегдердин калганын табалы. Келгиле, циклдин мисалы менен баштайлы:
public Set<String> getDistinctTags() {
Set<String> result = new HashSet<>();
for (Article article : articles) {
result.addAll(article.getTags());
}
return result;
}
Макул, агым операцияларын колдонуу менен муну кантип чече аларыбызды карап көрөлү:
public Set<String> getDistinctTags() {
return articles.stream()
.flatMap(article -> article.getTags().stream())
.collect(Collectors.toSet());
}
Баракелде! flatmap
тегдердин тизмесин бир жыйынтык агымына түздөөгө жардам берет, биз аны collect
кайра кайтаруу топтомун түзүү үчүн колдонобуз.
GO TO FULL VERSION