使用流和 Java 8 的 If/else 表示

Was*_*bel 27 java java-8 java-stream

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

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我去检查传入的消息并解析"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());
    }

}
Run Code Online (Sandbox Code Playgroud)

好吧,还不错。但是如果 message 不是"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());
Run Code Online (Sandbox Code Playgroud)

我该怎么做?

Jas*_*son 26

这是何时使用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
}
Run Code Online (Sandbox Code Playgroud)


luk*_*302 5

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

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

然后通过使用它

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

或者删除 DefaultParser 并执行

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