一篇文章拥有一个标题,一个做者和几个标签。this
private class Article {对象
private final String title;get
private final String author;it
private final List<String> tags;io
private Article(String title, String author, List<String> tags) {for循环
this.title = title;class
this.author = author;stream
this.tags = tags;List
}循环
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public List<String> getTags() {
return tags;
}
}
每一个例子都会包含一个使用传统循环的方案和一个使用Java 8新特性的方案。
在第一个例子里,咱们要在集合中查找包含“Java”标签的第一篇文章。
看一下使用for循环的解决方案。
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() 操做去获取第一次出现的文章。由于Stream是“延迟计算”(lazy)的而且filter返回一个流对象,因此这个方法仅在找到第一个匹配元素时才会处理元素。
如今,让咱们获取全部匹配的元素而不是仅获取第一个。
首先使用for循环方案。
public List<Article> getAllJavaArticles() {
List<Article> result = new ArrayList<>();
for (Article article : articles) {
if (article.getTags().contains("Java")) {
result.add(article);
}
}
return result;
}
使用Stream操做的方案。
public List<Article> getAllJavaArticles() {
return articles.stream()
.filter(article -> article.getTags().contains("Java"))
.collect(Collectors.toList());
}
在这个例子里咱们使用 collection 操做在返回流上执行少许代码而不是手动声明一个集合并显式地添加匹配的文章到集合里。
到目前为止还不错。是时候举一些突出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 方法,咱们获得了更简洁、可读性更高的代码。
如今,咱们查找集合中全部不一样的标签。
咱们从使用循环的例子开始。
public Set<String> getDistinctTags() {
Set<String> result = new HashSet<>();
for (Article article : articles) {
result.addAll(article.getTags());
}
return result;
}
好,咱们来看看如何使用Stream操做来解决这个问题。
public Set<String> getDistinctTags() {
return articles.stream()
.flatMap(article -> article.getTags().stream())
.collect(Collectors.toSet());
}
棒极了!flatmap 帮我把标签列表转为一个返回流,而后咱们使用 collect 去建立一个集合做为返回值。