Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If/else representation with stream and Java 8

I have the following interface with two implementations:

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");     } } 

I go to check incoming message and parse "stackoverflow" or "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());     }  } 

Okay, pretty good. But what if message is not "stackoverflow" or "youtube"? App will be silent, but I want to send another default message if no matches were found, like "I can't parse this web!".

I know that will not works (even compile), but it's also should print "I can't parse this web" only one time, not for every false condition.

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

How can I do it?

like image 532
Wasteland Rebel Avatar asked Jun 14 '20 12:06

Wasteland Rebel


People also ask

Does Java 8 support streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

How does stream works in Java 8?

Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.

How do you write if else in Java 8?

One Line if-else Statement Using filter in Java 8The streams filter method takes a Predicate and behaves like if-else in Java language. The above program instantiates a list using Arrays. asList() method.

How do you do if else in Java stream?

Conventional if/else Logic Within forEach() First of all, let's create an Integer List and then use conventional if/else logic within the Integer stream forEach() method: List<Integer> ints = Arrays. asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ints. stream() .


2 Answers

This is a perfect example of when to use the Optional#orElse or the Optional#orElseThrow method(s). You want to check if some condition is met so you filter, trying to return a single result. If one does not exist, some other condition is true and should be returned.

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 } 
like image 140
Jason Avatar answered Sep 23 '22 03:09

Jason


In case only one parser can parse the message at a time you could add a default parser:

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

And then use it via

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

or alternatively drop the DefaultParser and just do

Optional<Parser> parser = parsers.stream().filter(p -> p.canParse(message)).findFirst(); if (parser.isPresent()) {     parser.get().parse(); } else {     // handle it  } 
like image 34
luk2302 Avatar answered Sep 26 '22 03:09

luk2302