AriseEVE
AriseEVE

Reputation: 49

Iterating on list with stream in java 8

what would be most optimal way to rewrite this iteration with java 8 stream().

for (name : names){
  if(name == a){
    doSomething();
    break;
  }
  if(name == b){
   doSomethingElse();
   break; 
 }
 if(name == c){
  doSomethingElseElse();
  break;
 }
}

Basically, iterating over the list with 3 conditions if any of them is satisfied want to break loop and in every condition want to call different method.

Upvotes: 0

Views: 11504

Answers (3)

Magnilex
Magnilex

Reputation: 11988

The answer by Eran is definitely the straightforward way of performing the search. However, I would like to propose a slightly different approach:

private static final Map<String, Runnable> stringToRunnable = new HashMap<>();

{
  stringToRunnable.put("a", this::doSomething);
  stringToRunnable.put("b", this::doSomethingElse);
  stringToRunnable.put("c", this::doSomethingElseElse);
}

public static void main(String[] args) {
  List<String> names = Arrays.asList("1", "2", "b", "a");
  names.stream()
      .filter(stringToRunnable::containsKey)
      .findFirst()
      .ifPresent(name -> stringToRunnable.get(name).run());
}

private void doSomethingElseElse() {
}

private void doSomethingElse() {
}

public void doSomething() {
}

The part that does the job is the code below, but I added it to a main() function assuming a, b, and c are strings. However, the idea would work with any datatype.

names.stream()
    .filter(stringToRunnable::containsKey)
    .findFirst()
    .ifPresent(name -> stringToRunnable.get(name).run());

The idea is to keep a map of keys and Runnables. By having Runnable as value it is possible to define a void method reference without parameters. The stream first filters away all values not present in the map, then finds the first hit, and executes its method if found.

Upvotes: 5

Eran
Eran

Reputation: 394106

You can use anyMatch to find the first element matching one of your conditions and terminate. Use side effects for calling the processing methods :

boolean found =
  names.stream()
       .anyMatch (name -> {
                  if (name.equals(a)) {
                    doSomething();
                    return true;
                  } else if (name.equals(b)) {
                    doSomethingElse ();
                    return true;
                  } else if (name.equals(c)) {
                    doSomethingElseElse ();
                    return true;
                  } else {
                    return false;
                  }
                }
              );

Pretty ugly, but does what you asked in a single iteration.

Upvotes: 6

the-red-paintings
the-red-paintings

Reputation: 83

Collection collection;
collection.forEach(name->{
    if(name.equals(a))){
       doSomething();

    }
    if(name.equals(b)){
        doSomethingElse();

    }
    if(name.equals(c)){
        doSomethingElseElse();

    }
});

Upvotes: -3

Related Questions