【问题标题】:Is there a way to write below piece of code in java 8 format?有没有办法以java 8格式编写下面的代码?
【发布时间】:2021-03-08 13:28:29
【问题描述】:

我正在编写一段代码来为 DDB 表创建分区键。 我有一个点分格式的长名字,可以有尽可能多的名字,用“。”分隔

例如qw.er.ty.ui

我希望下面的方法将上述名称的子名称返回为“SUBNAME_qwer”。即“SUBNAME_”+名字+第二名。 其中 first name 是长名称中第一个点之前的字符串。 第二个名字是第一个点之后第二个点之前的字符串。

我不想对代码的行为进行任何更改,但想以 JAVA 8 方式编写它。 有可能吗?

片段 1:

    //name is a dotted format hierarchical name. e.g. n.x.y.c
    String getFirstTwoSubNames(final String name) {
        if (name == null) {
            throw new IllegalArgumentException("can't be null");
        }
        if (name.contains(".")) {
            String[] subNames = name.split("\\.");
            String firstTwoSubNames = subNames[0] + subNames[1];
            return String.join("_", "SUBNAME", firstTwoSubNames);

        } else {
            throw new IllegalArgumentException("Invalid format");
        }
    }

更新 1: 很抱歉把我的问题写得这么差。我是 JAVA 8 和堆栈溢出的新手。 这里的要求是删除命令式编码并采用 JAVA 8 的函数式编码风格。 到目前为止,在 @Alex Rudenko's 回答的帮助下,我能够将上述代码转换为功能性 JAVA 8-y 代码,如下所示:

片段 2:

 String getFirstTwoSubNames(final String name) {
       return "SUBNAME_" + Arrays.stream(Optional.ofNullable(name)
                    .orElseThrow(IllegalArgumentException::new)
                    .split("\\."))
                    .limit(2)
                    .collect(Collectors.joining(""));
    }

如您所见,我缺少从代码 sn-p 1 中抛出无效异常的逻辑。我希望以函数的方式将其包含在代码 sn-p 2 中。希望这会带来更多澄清我的问题。

【问题讨论】:

  • 当前代码有什么问题?为什么需要重写?您可能可以将其作为可选链来执行,但我怀疑这会有所改进。
  • 你认为结果会是什么样子?
  • @NikolasCharalambidis 给出的逻辑,似乎n.x.y.c 将被转换为SUBNAME_nx
  • String.join(…) 已经是 Java 8 方法。不过,它的使用在这里毫无意义,因为"SUBNAME_" + subNames[0] + subNames[1] 更简单。您可以将if (name == null) { throw new IllegalArgumentException("can't be null"); } 替换为requireNonNull(name, "can't be null"); 此外,您可以简单地在String[] subNames = name.split("\\."); 之后添加if(subNames.length == 1) throw new IllegalArgumentException("Invalid format");,而不是name.contains(".") 预检查

标签: java java-8 functional-programming java-stream purely-functional


【解决方案1】:

类似“Java 8”的解决方案可能是使用 Stream.limit 仅获取 2 个子名称和 Collectors.joining("")

勾选name.contains(".")可以去掉,拆分输入字符串后定义。

String getFirstTwoSubNames(final String name) {
    if (name == null) {
        throw new IllegalArgumentException("can't be null");
    }
    String[] subNames = name.split("\\.");
    if (subNames.length < 2) {
        throw new IllegalArgumentException("Invalid format");
    }
    return "SUBNAME_" + Arrays.stream(subNames).limit(2).collect(Collectors.joining(""));
}

更新

更新后的代码 sn -p #2 可能会被重构为将验证代码分离到单独的方法中,以便getFirstTwoSubnames 仅使用有效名称:

static String validName(String name) {
    return Stream.of(Optional.ofNullable(name).orElseThrow(NullNameException::new))
                 .filter(name -> name.contains("."))
                 .findFirst()
                 .orElseThrow(MinSubnamesException::new);
}

static String getFirstTwoSubNames(final String name) {
    return "SUBNAME_" + Arrays.stream(validName(name).split("\\."))
                              .limit(2)
                              .collect(Collectors.joining());
}

//--------
// customized exceptions
class NullNameException extends NullPointerException {
    public NullNameException() {
        super("Name cannot be null");
    }
}

class MinSubnamesException extends IllegalArgumentException {
    public MinSubnamesException() {
        super("A name must contain at least two sub-names separated with dot `.`");
    }
}

【讨论】:

  • 这看起来几乎没有 Java8-y。这都是命令式外壳,只需一点点就变成了更实用的样式。
  • 你有没有觉得Arrays.stream(subNames).limit(2).collect(Collectors.joining(""))subNames[0] + subNames[1] 有所改进?
  • @Holger,我没有这种感觉 :)
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 2020-06-27
  • 2020-10-06
  • 1970-01-01
相关资源
最近更新 更多