Java 8:新特性不要再用循环了

news/2024/5/19 12:05:00 标签: Java8新特性

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

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

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


开始编码!

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

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

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循环的解决方案。

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 去创建一个集合作为返回值。

一切皆有可能

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

原文链接:  deadcoderising  翻译:  ImportNew.com  进林
译文链接:  http://www.importnew.com/14841.html

http://www.niftyadmin.cn/n/1581408.html

相关文章

我得工作节拍(新产品、旧产品、文档、外包)

最近手上的工作很乱&#xff0c;归纳一下有:产品维护、新产品研发、外包项目、文档编制。 产品维护&#xff1a; 公司的原有产品开发了很长一段时间是公司的主打产品&#xff0c;但是随着用户的增多&#xff0c;产品的维护方式远远不能满足具体工作的需要&#xff0c;因此需要一…

Java 8 特性 – 终极手册

文章查看链接&#xff1a;http://www.importnew.com/19345.html

Java中的-let顿悟

最近初步学习J2EE的内容&#xff0c;而JSP正是J2EE的重要表现形式&#xff0c;后台是复杂的商业逻辑&#xff08;业务层等&#xff09;和数据、数据访问等。看到Servlet其及功能时&#xff0c;突然发现*let的有趣规律。 这里有几个*let&#xff1a;scriptlet、servlet、applet和…

Java基础数组

一.数组的简介 java中的数组、是一种简单的线性数据存储结构、他用牺牲自动扩展大小来换取与集合相比的唯一优势——查询效率的提升。他本身是一种引用类型的数据、所以我们要使用数组就要首先声明、初始化他、而他的初始化的完成也就意味着此数组的大小将不再改变、而且具有初…

两个将简体中文网页自动转为繁体中文网的页简单方法 (原理非常简单,尚不完善 IHttpHandler Proxy / Response.Filter)...

一: /* 将"任意"在线简体中文网页转为繁体中文页简单方法 以前都写在 Aspx 的 Codebehind 里用 WebRequest 抓别人的网页 ASP 时代用 XMLHTTP Object 抓 1. Microshaoft.HttpHandlers.cs 保存到 IIS 站点或某虚拟目录下的 \bin\Microshaoft.HttpHandlers.cs 2. cs…

spring 框架学习(1)

1.spring&#xff08;由Rod Johnson创建的一个开源框架&#xff09; Spring是一个开源框架&#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架&#xff0c;由Rod Johnson创建。简单来说&#xff0c;Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架…

【ZT】在.NET环境中使用单元测试工具NUnit

作者&#xff1a; shanyou www.ASPCool.com 时间:2003-12-5 17:42:13 阅读次数:4454 简介 编写单元测试是一种验证行为&#xff0c;更是一种设计行为。同样&#xff0c;它更是一种编写文档的行为。编写单元测试避免了相当数量的反馈循环&#xff0c;尤其是功能验证方面的反…

spring框架学习(2)

1.spring框架介绍 Spring是一个开源框架&#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架&#xff0c;由Rod Johnson创建。简单来说&#xff0c;Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。 2.spring架构图 1).IoC(Inversion of Control)…