有没有一种方法可以用Java8格式编写下面的代码?
我正在编写一段代码,用于为DDB表创建分区键。 我有点格式的长名称,可以有尽可能多的名称,以“.”分隔 e、 g.qw.er.ty.ui 我希望下面的方法将上面名称的子名称返回为“subname_qwer”。i、 e“子名称”+第一个名称+第二个名称。 其中,first name是长名称中第一个点之前的字符串。 第二个名称是第一个点之后第二个点之前的字符串 我不想对代码的行为做任何更改,但想用Java8的方式编写它。 可能吗 片段1:有没有一种方法可以用Java8格式编写下面的代码?,java,java-8,functional-programming,java-stream,purely-functional,Java,Java 8,Functional Programming,Java Stream,Purely Functional,我正在编写一段代码,用于为DDB表创建分区键。 我有点格式的长名称,可以有尽可能多的名称,以“.”分隔 e、 g.qw.er.ty.ui 我希望下面的方法将上面名称的子名称返回为“subname_qwer”。i、 e“子名称”+第一个名称+第二个名称。 其中,first name是长名称中第一个点之前的字符串。 第二个名称是第一个点之后第二个点之前的字符串 我不想对代码的行为做任何更改,但想用Java8的方式编写它。 可能吗 片段1: //name is a dotted format
//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:
对不起,我的问题写得这么差。我不熟悉Java8和堆栈溢出。
这里的任务是删除命令式编码,采用Java8的函数式编码风格。
到目前为止,在@Alex Rudenko的回答的帮助下,我能够将上述代码转换为功能性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(""));
}
如您所见,我缺少从代码片段1引发无效异常的逻辑。我希望以功能性的方式将其包含在代码片段2中。希望这能使我的问题更加清晰。类似于“Java 8”的解决方案可以使用流。限制
只提取2个子名称和收集器。加入(“”
)
可以删除检查name.contains(“.”
,它可以在拆分输入字符串后定义
String getFirstTwoSubNames(最终字符串名){
if(name==null){
抛出新的IllegalArgumentException(“不能为null”);
}
String[]subNames=name.split(“\\”);
if(子名称长度<2){
抛出新的IllegalArgumentException(“无效格式”);
}
返回“SUBNAME_”+Arrays.stream(subNames).limit(2).collect(collector.joining)(“”);
}
更新 更新后的代码片段#2可能会被重构,以将验证代码分离到单独的方法中,以便
getFirstTwoSubnames
仅使用有效名称:
静态字符串有效名称(字符串名称){
返回Stream.of(可选的.ofNullable(name).orElseThrow(NullNameException::new))
.filter(名称->名称.contains(“.”)
.findFirst()
.orelsetrow(MinSubnamesException::new);
}
静态字符串getFirstTwoSubNames(最终字符串名){
返回“SUBNAME\”+Arrays.stream(validName(name).split(“\\”))
.限额(2)
.collect(收集器.joining());
}
//--------
//自定义异常
类NullNameException扩展了NullPointerException{
公共NullNameException(){
超级(“名称不能为空”);
}
}
类MinSubnamesException扩展了IllegalArgumentException{
public MinSubnamesException(){
super(“一个名称必须至少包含两个子名称,以点“.”分隔);
}
}
当前代码有什么问题?为什么需要重新编写?你可能可以把它作为一个可选的链来做,但我怀疑它是否会有改进。你认为结果会是什么样子?@NikolasCharalambidis根据逻辑,似乎n.x.y.c
将被转换成SUBNAME\u nx
String。join(…)
已经是一个Java 8方法了。尽管如此,它在这里的使用是毫无意义的,因为“SUBNAME_”+subNames[0]+subNames[1]
更简单。如果(name==null){throw new IllegalArgumentException(“不能为null”);}替换为进一步,而不是name.contains(“.”
预检查,如果(subNames.length==1)throw new IllegalArgumentException(“无效格式”)在字符串[]子名称=name.split(“\\”)之后的code>代码>这看起来几乎是Java8-y。这是一个命令式shell,只需要一点点就可以变成一个更具功能性的样式。你是否觉得数组.流(子名称).限制(2).收集(收集器.加入(“”)
比子名称[0]+子名称[1]
有所改进?@Holger,我没有这种感觉:)