提问者:小点点

具有流和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”呢? 应用程序将处于静默状态,但如果没有找到匹配项,我想发送另一条默认消息,例如“我无法解析此Web!”

我知道这不起作用(即使编译),但它也应该只打印一次“我不能解析此Web”,而不是针对每个false条件。

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

我怎么能做到呢?


共3个答案

匿名用户

这是关于何时使用可选#orelse可选#orelseThrow方法的完美示例。 您希望检查是否满足某些条件,因此进行筛选,尝试返回单个结果。 如果一个不存在,则其他一些条件为真,应返回。

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

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

匿名用户

您可以在内部简单地使用forEach if-else

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

匿名用户

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

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 
}