处理空参数的函数式方法
Functional way to deal with null arguments
我想在工作中编写更实用的 java 代码。
但是我怎样才能重构像下面这样的东西。
该代码有效,它必须解析像 100/100 这样的字符串和 return 对整数。
private static final Pattern pattern = Pattern.compile("^(\d+)(/)(\d+)$");
public static Optional<Pair<Integer, Integer>> foo(String str) {
var matcher = pattern.matcher(str != null ? str : "");
return matcher.find() && matcher.groupCount() == 3 ?
Optional.of(new Pair<Integer,Integer>(Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(3)))):
Optional.empty();
}
}
public static Optional<Pair<Integer, Integer>> foo(String input) {
return Optional.ofNullable(input)
.map(str -> pattern.matcher(str))
.filter(matcher -> matcher.find() && matcher.groupCount() == 3)
.map(matcher -> new Pair<Integer, Integer>(
Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(3))
));
}
最好始终以 Optional
开头,这样可以避免所有空值检查。通常应该避免 Optional.of()
或 Optional.empty()
只做最后的结果:
Optional.of()
没有任何进一步的操作是一种代码味道。这意味着您永远不必做任何需要空检查开始的事情。是的,有这种情况,但很少见。如果您找到这样的代码,请务必仔细查看。
通常,代码应以 Optional.of()
或 Optional.ofNullable()
开头,然后以 .map()
或其他方法继续。
Optional.empty()
类似。这意味着您甚至不需要检查是否为空,只需返回一个空结果。好吧,有些情况下您可以使用此快捷方式,但通常 Optional
的要点是从 something 开始并对其进行操作。操作的结果可能会产生一个空结果。
通常 正确 使用 Optional.empty()
是在开始时完成的——首先进行一些检查,然后生成一个空的可选项,如 an early return。小心返回 Optional.empty()
last 或在您已经构建了 Optional
之后。
首先,需要固定模式以允许多个数字,并且不需要为 /
分隔符使用单独的组:
pattern = Pattern.compile("^(\d+)/(\d+)$");
接下来,输入参数可能使用Optional.ofNullable
,Optional::flatMap
来处理解析输入字符串后返回的Optional<Pair>
。
public static Optional<Pair<Integer, Integer>> foo(String str) {
return Optional.ofNullable(str)
.flatMap(s -> pattern.matcher(s)
.results()
.map(mr -> new Pair<>(Integer.valueOf(mr.group(1)), Integer.valueOf(mr.group(2)))) // Stream<Pair>
.findFirst() // Optional<Pair>
);
}
测试:
System.out.println(foo("100/100"));
System.out.println(foo(null));
System.out.println(foo("abcd"));
输出:
Optional[100, 100]
Optional.empty
Optional.empty
更正 Java VLAZ 的 8 个友好解决方案可能如下所示:
public static Optional<Pair<Integer, Integer>> foo(String str) {
return Optional.ofNullable(str)
.map(pattern::matcher)
.filter(Matcher::matches) // no need to use find() for the given pattern
.map(matcher -> new Pair<>(
Integer.valueOf(matcher.group(1)),
Integer.valueOf(matcher.group(2))
));
}
我想在工作中编写更实用的 java 代码。 但是我怎样才能重构像下面这样的东西。
该代码有效,它必须解析像 100/100 这样的字符串和 return 对整数。
private static final Pattern pattern = Pattern.compile("^(\d+)(/)(\d+)$");
public static Optional<Pair<Integer, Integer>> foo(String str) {
var matcher = pattern.matcher(str != null ? str : "");
return matcher.find() && matcher.groupCount() == 3 ?
Optional.of(new Pair<Integer,Integer>(Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(3)))):
Optional.empty();
}
}
public static Optional<Pair<Integer, Integer>> foo(String input) {
return Optional.ofNullable(input)
.map(str -> pattern.matcher(str))
.filter(matcher -> matcher.find() && matcher.groupCount() == 3)
.map(matcher -> new Pair<Integer, Integer>(
Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(3))
));
}
最好始终以 Optional
开头,这样可以避免所有空值检查。通常应该避免 Optional.of()
或 Optional.empty()
只做最后的结果:
Optional.of()
没有任何进一步的操作是一种代码味道。这意味着您永远不必做任何需要空检查开始的事情。是的,有这种情况,但很少见。如果您找到这样的代码,请务必仔细查看。通常,代码应以
Optional.of()
或Optional.ofNullable()
开头,然后以.map()
或其他方法继续。Optional.empty()
类似。这意味着您甚至不需要检查是否为空,只需返回一个空结果。好吧,有些情况下您可以使用此快捷方式,但通常Optional
的要点是从 something 开始并对其进行操作。操作的结果可能会产生一个空结果。通常 正确 使用
Optional.empty()
是在开始时完成的——首先进行一些检查,然后生成一个空的可选项,如 an early return。小心返回Optional.empty()
last 或在您已经构建了Optional
之后。
首先,需要固定模式以允许多个数字,并且不需要为 /
分隔符使用单独的组:
pattern = Pattern.compile("^(\d+)/(\d+)$");
接下来,输入参数可能使用Optional.ofNullable
,Optional::flatMap
来处理解析输入字符串后返回的Optional<Pair>
。
public static Optional<Pair<Integer, Integer>> foo(String str) {
return Optional.ofNullable(str)
.flatMap(s -> pattern.matcher(s)
.results()
.map(mr -> new Pair<>(Integer.valueOf(mr.group(1)), Integer.valueOf(mr.group(2)))) // Stream<Pair>
.findFirst() // Optional<Pair>
);
}
测试:
System.out.println(foo("100/100"));
System.out.println(foo(null));
System.out.println(foo("abcd"));
输出:
Optional[100, 100]
Optional.empty
Optional.empty
更正 Java VLAZ 的 8 个友好解决方案可能如下所示:
public static Optional<Pair<Integer, Integer>> foo(String str) {
return Optional.ofNullable(str)
.map(pattern::matcher)
.filter(Matcher::matches) // no need to use find() for the given pattern
.map(matcher -> new Pair<>(
Integer.valueOf(matcher.group(1)),
Integer.valueOf(matcher.group(2))
));
}