【问题标题】:Java8 Optional with Function chaining expression [closed]带有函数链接表达式的Java8可选[关闭]
【发布时间】:2016-01-21 22:33:05
【问题描述】:

我想知道有没有办法简化下面的代码?我正在尝试使用 EBean 从数据库中获取一些东西。如果有东西,则将其映射到一个对象或以其他方式返回默认实现实例。

public static ObjectA test1() {

    Function<Optional<SqlRow>, ObjectA> sqlRowToObjectA= new Function<Optional<SqlRow>, ObjectA>() {
        @Override
        public AccountSummary apply(Optional<SqlRow> entry) {
            return entry.isPresent() ? new ObjectA(entry.get().getInt("id"), entry.get().getString("name"))
                 : ObjectA.EMPTY;
        }
    };

    return sqlRowToObjectA.apply(Optional.of(Ebean.createSqlQuery("select * from table1").findUnique()));
}

【问题讨论】:

  • 我认为您可以将条目映射到新创建的对象中,或者返回一个空元素。
  • @MiserableVariable 更容易理解并且可以像链接时尚一样完成?
  • 定义更容易理解

标签: java lambda functional-programming java-8 optional


【解决方案1】:

您可以使用 lambda 而不是匿名类 - 并使用 map 来获得所需的结果 + orElse 作为默认值:

Function<Optional<SqlRow>, ObjectA> sqlRowToObjectA =
    entry -> entry.map(e -> new ObjectA(e.getInt("id"), e.getString("name")))
                  .orElse(ObjectA.EMPTY);

但是,在您的示例中,您根本不需要 Function 并且可以像这样重写整个方法:

public static ObjectA test1() {
  SqlRow row = Ebean.createSqlQuery("select * from table1").findUnique();

  return Optional.ofNullable(row)
                 .map(e -> new ObjectA(e.getInt("id"), e.getString("name")))
                 .orElse(ObjectA.EMPTY);
}

请注意,因为findUnique 可能返回null,您应该使用Optional.ofNullable() 而不是Optional.of():如果该行是null,后者将抛出异常。


最后,我要补充一点,这样写起来会更简单、更高效:

public static ObjectA test1() {
  SqlRow row = Ebean.createSqlQuery("select * from table1").findUnique();

  return row == null ? ObjectA.EMPTY
                     : new ObjectA(row.getInt("id"), row.getString("name"));
}

或者更改方法签名,让调用者决定如果没有结果怎么办:

public static Optional<ObjectA> test1() {
  SqlRow row = Ebean.createSqlQuery("select * from table1").findUnique();

  return Optional.ofNullable(row)
                 .map(e -> new ObjectA(e.getInt("id"), e.getString("name")));
}

【讨论】:

  • 最后一行(返回)看起来一样吗?
  • 是的,一个函数就是一个函数……但是你可以完全跳过这个函数,直接在Optional.of(Ebean.createSqlQuery("select * from table1").findUnique())上调用map。
  • map 如果可选项有值,则将 SqlRow 转换为 ObjectA - 否则调用 orElse 以创建空 ObjectA。我建议您阅读javadoc 了解更多详情。
  • 请注意,仍然存在逻辑错误:Optional.of(…) 永远不会返回一个空的可选项,因此如果这是有意使用,则此处完全不需要使用 Optional。另一方面,如果它应该处理由findUnique 返回的可能的null,那么您必须使用Optional.ofNullable。 @assylias 也许最好包含一个完整的用法示例,它不使用这个过时的 sqlRowToObjectA 函数并正确创建初始 Optional
  • 最后一句话。 maporElse 不仅仅是 ifelse 等价物。它甚至可以替换嵌套的if 语句,因为当映射函数返回null(这里不可能发生)时,结果将是一个空的可选项,导致orElse 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2017-01-27
  • 2012-12-05
  • 2019-03-24
  • 2021-06-24
  • 2021-11-15
  • 1970-01-01
相关资源
最近更新 更多