Java 8函数式编程模式:不要使用匿名函数

栏目: Java · 发布时间: 7年前

内容简介:本文将引导你完成一系列从传统的命令式代码重构到Java 8函数代码,要从本文中获得最大收益,你应该具备Java 8函数的一些实践经验。为了热身,让我们从简单的任务开始,将一些用户的详细信息带到UI。我们将从实体列表的开始,将User 转换到 UserDto:

本文将引导你完成一系列从传统的命令式代码重构到 Java 8函数代码,要从本文中获得最大收益,你应该具备Java 8函数的一些实践经验。

1)优先于匿名Lambda的命名函数

为了热身,让我们从简单的任务开始,将一些用户的详细信息带到UI。我们将从实体列表的开始,将User 转换到 UserDto:

<b>public</b> List<UserDto> getAllUsers() {
        List<User> users = userRepo.findAll();
        List<UserDto> dtos = <b>new</b> ArrayList<>();
        <b>for</b> (User user : users) {
                UserDto dto = <b>new</b> UserDto();
                dto.setUsername(user.getUsername());
                dto.setFullName(user.getFirstName() + <font>" "</font><font> + user.getLastName().toUpperCase());
                dto.setActive(user.getDeactivationDate() == <b>null</b>);
                dtos.add(dto);
        }
        <b>return</b> dtos;
}
</font>

但是,我对这段代码并不感到自豪,因为我很可能会为许多用例重复编写类似的代码。那么,让我们使用Java 8:

<b>public</b> List<UserDto> getAllUsers() {
        <b>return</b> userRepo.findAll().stream()
                .map(user -> {
                        UserDto dto = <b>new</b> UserDto();
                        dto.setUsername(user.getUsername());
                        dto.setFullName(user.getFirstName() + <font>" "</font><font> + user.getLastName().toUpperCase());
                        dto.setActive(user.getDeactivationDate() == <b>null</b>);
                        <b>return</b> dto;
                })
                .collect(toList());
</font>

虽然不错,但是,我仍然不满意。我写的这个lambda演示了一个“匿名函数”。作为一个干净的代码疯子,我有一个问题 - 我想要富有表现力的名字。所以,我很快将lambda内容提取到一个单独的方法中:

<b>public</b> List<UserDto> getAllUsers() {
        <b>return</b> userRepo.findAll().stream().map(<b>this</b>::toDto).collect(toList());
}
<b>private</b> UserDto toDto(User user) {
        UserDto dto = <b>new</b> UserDto();
        dto.setUsername(user.getUsername());
        dto.setFullName(user.getFirstName() + <font>" "</font><font> + user.getLastName().toUpperCase());
        dto.setActive(user.getDeactivationDate() == <b>null</b>);
        <b>return</b> dto;
}
</font>

代码比在之前的版本中更简单,但现在它稍微好一些。

这种User到DTO的逻辑转换可以直接放在DTO构造函数中:

<b>public</b> <b>class</b> UserFacade {
        <b>private</b> UserRepo userRepo;        
        <b>public</b> List<UserDto> getAllUsers() {
                <b>return</b> userRepo.findAll().stream().map(UserDto::<b>new</b>).collect(toList());
        }
}
<b>public</b> <b>class</b> UserDto {
        <b>private</b> String username;
        <b>private</b> String fullName;
        <b>private</b> <b>boolean</b> active;
        <b>public</b> UserDto(User user) {
                username = user.getUsername();
                fullName = user.getFirstName() + <font>" "</font><font> + user.getLastName().toUpperCase();
                active = user.getDeactivationDate() == <b>null</b>;
        }
        ...
}
</font>

现在,让我们假设这个转换需要一些其他组件的帮助,我们希望使用Spring,Guice,CDI等注入。但是,在我们实例化的类中注入依赖项需要非常复杂的代码。如果这个转换过于复杂,我们应该将它移到一个单独的UserMapper类并从那里引用它:

@Service
<b>public</b> <b>class</b> UserFacade {
          @Autowired
          <b>private</b> UserRepo userRepo;
          @Autowired
          <b>private</b> UserMapper mapper;         
          <b>public</b> List<UserDto> getAllUsers() {
                   <b>return</b> userRepo.findAll().stream().map(mapper::toDto).collect(toList());
          }
}
@Component
<b>public</b> <b>class</b> UserMapper {
          @Autowired
          <b>private</b> OtherClass otherClass;
          <b>public</b> UserDto toDto(User user) {
                   UserDto dto = <b>new</b> UserDto();
                   dto.setUsername(user.getUsername());
                   ... <font><i>// code using otherClass</i></font><font>
                   <b>return</b> dto;
          }
}
</font>

关键点是:始终将复杂的lambda提取到具有表达名称的函数中,然后可以使用以下四点(::)来引用:

  • 如在同一个类,使用this::;
  • 在另外一个类似于(mapper::);
  • 一些静态助手方法(SomeClass::);
  • Stream 中条目类型(Item::);
  • 甚至一些构造函数(),如果它足够简单;UserDto::new

记住,不要使用匿名类型。

这个GitHub存储库中 提交了练习的每个阶段,所以请随意浏览存储库以查看所有内容。


以上所述就是小编给大家介绍的《Java 8函数式编程模式:不要使用匿名函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人工智能时代

人工智能时代

[ 美]杰瑞•卡普兰(Jerry Kaplan) / 李盼 / 浙江人民出版社 / 2016-4-1 / CNY 59.90

 当机器人霸占了你的工作,你该怎么办?机器人犯罪,谁才该负责?人工智能时代,人类价值如何重新定义?  在《人工智能时代》一书中,智能时代领军人、硅谷连续创业者杰瑞·卡普兰指出:智能时代的到来,给人类社会带来了两大灾难性冲击:持续性失业与不断加剧的贫富差距。机器正在很大程度上替代人类的工作,不管你是蓝领还是白领。而针对未来社会将要发生的这些问题,卡普兰在《人工智能时代》一书中从企业、税收和......一起来看看 《人工智能时代》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具