soword科技言
永久公益免费API接口
提供永久免费的API接口,查看更多API接口,如果您有其他免费API资源,请联系我们,造福人类。
提供商务开发:小程序,系统,APP
定制开发,免费评估,免费咨询,价格便宜,售后保障,前往开发服务中心联系开发客服中心
流和Java 8的if / else表示

我有以下两个实现的界面:

public interface Parser {
void parse();
boolean canParse(String message);}class StackParser implements Parser {
public void parse(){
System.out.println("Parsing stackoverflow");
}
public boolean canParse(String message){
return message.equals("stackoverflow");
}}class YoutubeParser implements Parser {
public void parse() {
System.out.println("Parsing youtube");
}
public boolean canParse(String message) {
return message.equals("youtube");
}}

我去检查传入的消息并解析"stackoverflow""youtube"

public class Main {
private List<Parser> parsers;


public static void main(String[] args) {
new Main().doSomething("youtube");
}

void doSomething(String message){
parsers.stream()
.filter(p -> p.canParse(message))
.forEach(p -> p.parse());
}}

好,很好 但是,如果消息不是"stackoverflow""youtube"怎么办?应用程序将保持静音,但如果未找到匹配项,我想发送另一条默认消息,例如"I can't parse this web!"

我知道这是行不通的(即使是编译),但也应该"I can't parse this web"打印一次,而不是针对每种false条件。

parsers.stream()
 .filter(p -> {
if (p.canParse(message) == false) {
 System.out.println("I can't parse it!");
 }
})
.forEach(p -> p.parse());

我该怎么做?

这是何时使用Optional#orElseOptional#orElseThrow方法的完美示例您想检查是否满足某些条件,以便进行过滤,尝试返回单个结果。如果不存在,则其他条件为真,应返回。

try {
Parser parser = parsers.stream()
.filter(p -> p.canParse(message))
.findAny()
.orElseThrow(NoParserFoundException::new);

// parser found, never null
parser.parse();} catch (NoParserFoundException exception) {
 // cannot find parser, tell end-user}

如果一次只有一个解析器可以解析消息,则可以添加默认解析器:

class DefaultParser implements Parser {
public void parse() {
System.out.println("Could not parse");
}
public boolean canParse(String message) {
return true;
}}

然后通过

// make sure the `DefaultParser` is the last parser in the `parsers`parsers.stream().filter(p -> p.canParse(message)).findFirst().get().parse();

或者删除DefaultParser并执行

Optional<Parser> parser = parsers.stream().filter(p -> p.canParse(message)).findFirst();if (parser.isPresent()) {
parser.get().parse();} else {
// handle it }

您可以在内部仅使用forEach if-else

parsers.forEach(p -> {
if (!p.canParse(message)) {
 System.out.println("I can't parse it!");
} else {
p.parse();
}
 });

这是一个非常有趣的问题,幸运的是我不得不在一段时间前面对。Mi方法包括声明Supplier<T>仅在抛出异常时才会迭代的列表(此方法的目的是根据给定的参数从数据库检索数据,因此我可以按id或实例进行搜索) 。

import java.util.function.Supplier;public class AbstractFacadeUtil {

public <R> R tryOr(Supplier<R>...fns) {
R result = null;
boolean success = false;
int i = 0;
while (!success && i < fns.length) {
Supplier<R> fn = fns[i++];
try {
result = fn.get();
success = true;
} catch (Exception e) {

}
}
if (!success) {
throw new RuntimeException(new Exception(String.format("[%s] Couldn't find a successful method to apply\"", this.getClass())));
}
return result;
}}

一些注意事项:

  • Supplier<T>之所以使用它是因为它的主体不包含任何会引发未声明异常的东西,否则将需要使用它Callable<T>

  • 是的,可以给它起一个更好的名字。

  • 也许Iterator<T>可以使这段代码更易于理解和清晰。

在您的特定情况下,我会使用Jason方法Supplier<T>,在列表的末尾添加一个会抛出NoParserFoundException

[编辑],你应该迭代List<Supplier<T>>List<Callable<T>>wheter的Parser无法解析,它抛出一个CantParseException因此,正如您所看到的,即使我不确定这是否是最有效或专家的方法,异常也会有所帮助。希望对您有帮助。

[EDIT2] 是我如何实现上述解决方案的示例。

好吧,我要说。查看发布的每个解决方案-您如何看待?它们是否是功能性方法所期望的简洁,干净的代码?

不,为什么?由于设计错误,因此不适合功能方法。

修复设计:

  1. 摆脱void返回类型(BRR)

  2. 不要过度使用类似的方法canDoSomething(像对待isPresentOptional-它的存在是有极端的情况下,大多是技术,而不是业务代码)

  3. 查看VAVR(或类似的库)-类TryEither等等。

那么,在每种情况下,解决方案都会自然而然地-不仅是您在此处发布的特定解决方案。



2023-03-22 10:04:19

新人小程序+APP定制199元起


发放福利,助力中小企业发展,真正在互联网中受益

点击询问定制

广告服务展示