【问题标题】:Java 8 code optimization - remove if statementsJava 8 代码优化 - 删除 if 语句
【发布时间】:2020-02-16 10:18:11
【问题描述】:

我正在学习 Java 8 的一些技巧。我创建了一个简单的列表:

 private void createData() {
        bottles.add(new Whiskey("Jack Daniels", "PL"));
        bottles.add(new Whiskey("Balentains", "PL"));
        bottles.add(new Whiskey("Balentains", "EN"));
        bottles.add(new Whiskey("Balentains", "EN"));
        bottles.add(new Whiskey("Balentains", "GR"));
        bottles.add(new Whiskey("Balentains", "PL"));
        bottles.add(new Whiskey("Balentains", "GR"));
    }

现在我想通过几件事从这个列表中获取项目。如果用户给一个参数origin,我想用origins过滤这个列表,但是当他给错误origin时他应该得到空列表,当他不给origin参数时他应该得到完整列表。

我有一个过滤列表中项目的方法:

 private Optional<List<Whiskey>> getWhiskeyFromCountry(String origin) {
        final List<Whiskey> whiskies = bottles.stream()
                .filter(b -> b.getOrigin().equals(origin))
                .collect(Collectors.toList());

        return whiskies.isEmpty() ? Optional.empty() : Optional.of(whiskies);
    }

也是一个获取参数(或不获取参数)和响应结果的主要方法:

private void getAll(RoutingContext routingContext) {
        Optional<String> origin = Optional.ofNullable(routingContext.request().params().get("filter"));
        List<Whiskey> result = getWhiskeyFromCountry(origin.orElse("")).orElse(Collections.EMPTY_LIST);

        routingContext.response()
                .putHeader("content-type", "application/json; charset=utf-8")
                .end(Json.encodePrettily(origin.isPresent() ? result : bottles));
    }

问题是我仍然在最后一行使用 if 语句,我不想​​这样做。我想将此代码更改为清晰实用。我试图用 Optionals 做一些魔法,但最后我得到了这个,我认为它可以做得更好更简单。你可以帮帮我吗?或者也许这段代码很好,我不需要改变任何东西?这个问题更多的是关于干净的代码。

【问题讨论】:

  • 只需从getWhiskeyFromCountry 方法返回一个List。如果origin 错误,列表将为空。
  • 为什么不直接返回空列表呢?应该也可以。
  • @AlexR - 没关系,但我仍然需要检查最后一行的 if 语句
  • 为什么要避免使用 if 语句?一个 if 语句很好、清晰、快速且可维护。功能代码链不是,而且性能很糟糕。
  • @allocer 不,如果您尝试使用流来最小化 if 语句,那么您就无法理解流、函数式编程以及编写可读性较差的代码。如果使用速度慢、性能低、可读性较差的函数调用,您正在替换一个不错的、易于阅读的高性能函数。这不是您应该尝试做的事情。这是糟糕的风格和糟糕的编程。

标签: java java-8 functional-programming optional


【解决方案1】:

你可以让这个方法getWhiskeyFromCountry接受Optional&lt;String&gt;作为参数

private List<Whiskey> getWhiskeyFromCountry(Optional<String> origin)

然后如果 Optional 为空返回空列表或返回基于filter 的列表,如果用户输入错误的origin 仍然会得到空列表

return origin.map(o->bottles.stream()
            .filter(b -> b.getOrigin().equals(o))
            .collect(Collectors.toList())).orElse(Collections.EMPTY_LIST);

或者在上面的代码中你可以做一些小的调整来返回List这个方法getWhiskeyFromCountry

 private List<Whiskey> getWhiskeyFromCountry(String origin) {

    return bottles.stream()
            .filter(b -> b.getOrigin().equals(origin))
            .collect(Collectors.toList());
  }

并且在主要方法中使用Optional.map

Optional<String> origin = Optional.ofNullable(routingContext.request().params().get("filter"));
List<Whiskey> result = origin.map(o->getWhiskeyFromCountry(o))
                             .orElse(bottles);

【讨论】:

  • Optional 作为参数传递不是最佳做法!
  • 我可以知道为什么@HadiJ 吗?
  • @Deadpool,虽然我不同意将origin 作为可选,但对于避免重复检查的第二种方法,我认为最好使用origin.map(o-&gt;getWhiskeyFromCountry(o)) .orElse(bottles);
  • 或者可能是这样的Optional&lt;String&gt; getParam(RoutingContext routingContext){return Optional.ofNullable(routingContext.request().params().get("filter"));}然后在getAll方法getParam(routingContext).map(o-&gt;getWhiskeyFromCountry(o)) .orElse(bottles);
  • 参考@HadiJ 指出的内容。 Why should Optional not be used in arguments.
猜你喜欢
  • 2010-12-31
  • 2023-03-28
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-18
  • 2017-02-27
相关资源
最近更新 更多