【问题标题】:Conditional initialization in most efficient and readable way以最有效和可读的方式进行条件初始化
【发布时间】:2018-10-29 09:16:11
【问题描述】:

有条件地初始化一个集合(在这个例子中是一个地图)最有效的方法是什么?就最佳实践而言,您更喜欢一种解决方案吗?

我提供了三个解决方案,想请教您的反馈或意见。

第一:

Map<String, User> userMap;
if (isNotEmpty(userIdList)) {
  userService
      .getUsers(userIdList)
      .stream()
      .collect(Collectors.toMap(UserDto::getUserName, Function.identity()));
} else {
  userMap = new HashMap<>();
}

第二:

Map<String, User> userMap = new HashMap<>();
if (isNotEmpty(userIdList)) {
  userService
      .getUsers(userIdList)
      .stream()
      .collect(Collectors.toMap(UserDto::getUserName, Function.identity()));
}

第三:

Map<String, User> userMap = isNotEmpty(userIdList) ?
    userService
    .getUsers(userIdList)
    .stream()
    .collect(Collectors.toMap(UserDto::getUserName, Function.identity()))
    : new HashMap<>();

这里的附加限制是您需要在使用userService.getUsers() 之前验证userIdList 是否为nullempty()

【问题讨论】:

  • 第一种方式和第三种方式基本相同。第二种方式效率稍低,但会破坏有效的确定性
  • userMap = userService... 在制定问题时迷路了。我最喜欢第三种解决方案。

标签: java if-statement initialization java-stream ternary-operator


【解决方案1】:

我会完全放弃条件。如果您流式传输一个空列表并将其收集到地图,您将获得一个空地图:

Map<String, User> userMap = 
    userService.getUsers(userIdList)
               .stream()
               .collect(Collectors.toMap(UserDto::getUserName, Function.identity()));

【讨论】:

  • 这里唯一的问题是空列表情况下的通话费用。
  • 假设您需要在使用userService.getUsers() 之前验证userIdList 是否为nullempty()
  • @Zychoo 看看Optional&lt;T&gt;
【解决方案2】:

初始化集合最有效的方法是什么?

如果没有userIdList,我会选择Collections.emptyMap(),如下所示。

Map<String, User> userMap;
if (isNotEmpty(userIdList)) {
  userService
      .getUsers(userIdList)
      .stream()
      .collect(Collectors.toMap(UserDto::getUserName, Function.identity()));
} else {
    userMap = Collections.emptyMap();
}

当您使用Collections.emptyMap() 时,它的意图非常清晰且更具可读性。

您可以查看Collection.emptyMap() API here

正如其他人已经提到的那样,Option(1) 和 Option(3) 之间没有区别。


尽管如此,您不会看到这件事的性能有任何大的差异(除非您在循环中执行此操作)。如果性能是真正的问题,那么只需检查应用程序内部的其他地方是否存在真正的瓶颈。

【讨论】:

  • 请注意Collections.emptyMap() 返回一个不可变的映射。根据代码中的进一步操作,这可能会导致刹车。
  • 当不可变的情况下,这将是最好的。另外。 Collections.emptyMap() 是否更高效,因为它不会创建新对象(成本很高)并且不会保留更多内存空间?
  • @mtj 这将是一件好事,因为Collectors.toMap(…) 也不保证返回可变映射。它确实返回一个可变的HashMap 的事实是根据未指定的实现细节创建代码的邀请。处理这个问题的最好方法是,将Collections.emptyMap() 用于空箱并将结果包装到Collection.unmodifiableMap(…) 中,以便尽早发现此类错误。如果我们需要可变地图,则必须使用带有地图工厂的收集器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
相关资源
最近更新 更多