java8 不使用循环

简介: Java 8中的新功能特性改变了游戏规则。对Java开发者来说这是一个全新的世界,并且是时候去适应它了。 在这篇文章里,我们将会去了解传统循环的一些替代方案。在Java 8的新功能特性中,最棒的特性就是允许我们去表达我们想要完成什么而不是要怎样做。

Java 8中的新功能特性改变了游戏规则。对Java开发者来说这是一个全新的世界,并且是时候去适应它了。

在这篇文章里,我们将会去了解传统循环的一些替代方案。在Java 8的新功能特性中,最棒的特性就是允许我们去表达我们想要完成什么而不是要怎样做。这正是循环的不足之处。要确保循环的灵活性是需要付出代价的。return、break 或者 continue都会显著地改变循环的实际表现。这迫使我们不仅要清楚我们要实现怎样的代码,还要了解循环是怎样工作的。

在介绍Java 8的流(Stream)时,我们学会了一些集合操作的实用技巧。现在我们要看看怎样把这些循环转换为更简洁,可读性更高的代码。


开始编码!

好吧,讲的够多了,是时候展示一些例子了!

这次我们要以文章为例子。一篇文章拥有一个标题,一个作者和几个标签。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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”标签的第一篇文章。

看一下使用for循环的解决方案。

1
2
3
4
5
6
7
8
9
10
public Article getFirstJavaArticle() {
 
     for (Article article : articles) {
         if (article.getTags().contains( "Java" )) {
             return article;
         }
     }
 
     return null ;
}

现在我们使用Stream API的相关操作来解决这个问题。

1
2
3
4
5
public Optional<Article> getFirstJavaArticle() { 
     return articles.stream()
         .filter(article -> article.getTags().contains( "Java" ))
         .findFirst();
     }

是不是很酷?我们首先使用 filter 操作去找到所有包含Java标签的文章,然后使用 findFirst() 操作去获取第一次出现的文章。因为Stream是“延迟计算”(lazy)的并且filter返回一个流对象,所以这个方法仅在找到第一个匹配元素时才会处理元素。

现在,让我们获取所有匹配的元素而不是仅获取第一个。

首先使用for循环方案。

1
2
3
4
5
6
7
8
9
10
11
12
public List<Article> getAllJavaArticles() {
 
     List<Article> result = new ArrayList<>();
 
     for (Article article : articles) {
         if (article.getTags().contains( "Java" )) {
             result.add(article);
         }
     }
 
     return result;
}

使用Stream操作的方案。

1
2
3
4
5
public List<Article> getAllJavaArticles() { 
     return articles.stream()
         .filter(article -> article.getTags().contains( "Java" ))
         .collect(Collectors.toList());
     }

在这个例子里我们使用 collection 操作在返回流上执行少量代码而不是手动声明一个集合并显式地添加匹配的文章到集合里。

到目前为止还不错。是时候举一些突出Stream API强大的例子了。

根据作者来把所有的文章分组。

照旧,我们使用循环方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}

我们能否找到一个使用流操作的简洁方案来解决这个问题?

1
2
3
4
public Map<String, List<Article>> groupByAuthor() { 
     return articles.stream()
         .collect(Collectors.groupingBy(Article::getAuthor));
}

很好!使用 groupingBy 操作和 getAuthor 方法,我们得到了更简洁、可读性更高的代码。

现在,我们查找集合中所有不同的标签。

我们从使用循环的例子开始。

1
2
3
4
5
6
7
8
9
10
public Set<String> getDistinctTags() {
 
     Set<String> result = new HashSet<>();
 
     for (Article article : articles) {
         result.addAll(article.getTags());
     }
 
     return result;
}

好,我们来看看如何使用Stream操作来解决这个问题。

1
2
3
4
5
public Set<String> getDistinctTags() { 
     return articles.stream()
         .flatMap(article -> article.getTags().stream())
         .collect(Collectors.toSet());
}

棒极了!flatmap 帮我把标签列表转为一个返回流,然后我们使用 collect 去创建一个集合作为返回值。

一切皆有可能

以上的就是如何使用可读性更高的代码代替循环的例子。务必仔细看看Stream API,因为这篇文章仅仅提到它的一些皮毛而已。

更新

收到solarfuse和dhruvgairola的评论后,更新了getDistinctTags()例子,使用集合(Set)作为返回集合。

相关文章
|
3月前
|
存储 Java
|
11天前
|
Java 测试技术 数据安全/隐私保护
📖Java零基础-while循环语句的深度解析
【10月更文挑战第6天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
15 1
|
12天前
|
传感器 Java 测试技术
📖Java零基础-do-while循环语句的深入剖析
【10月更文挑战第5天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
10 1
|
2月前
|
Java
java基础(2)循环语句for、while、do...while
本文介绍了Java中的基础循环语句,包括for循环、while循环和do...while循环。文章通过示例代码展示了for循环的基本结构和用法,while循环的先判断后执行逻辑,以及do...while循环的先执行后判断逻辑。这些循环语句在Java编程中非常常用,用于执行重复的任务。
41 4
java基础(2)循环语句for、while、do...while
|
6月前
|
Java
Java的控制流程语句:深入理解条件语句、循环语句与跳转语句
Java的控制流程语句:深入理解条件语句、循环语句与跳转语句
60 1
|
2月前
|
Java
Java循环
Java循环
41 6
|
2月前
|
编译器
Java--for循环语句
Java--for循环语句
|
3月前
|
存储 Java
如何在 Java 中循环 ArrayList
【8月更文挑战第23天】
31 2
|
3月前
|
Java
Java 流程控制15道练习题(选择&循环)
Java 流程控制15道练习题(选择&循环)
55 10
|
3月前
|
Java 机器人 开发者
04 Java流程控制-循环(while+for+关键字+嵌套)
04 Java流程控制-循环(while+for+关键字+嵌套)
57 4