If/else 表示流和 Java 8

2022-09-01 15:48:13

我有以下两个实现的接口:

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());

我该怎么做?


答案 1

这是何时使用 或 方法 的一个完美示例。您希望检查是否满足某些条件,以便进行筛选,尝试返回单个结果。如果不存在,则其他条件为真,应返回。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
}

答案 2

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

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 
}

推荐