425 Stimmen

Unterbrechen oder zurückkehren vom Java 8 Stream forEach ?

Beim Verwenden einer externen Iteration über ein Iterable verwenden wir break oder return aus einer verbesserten for-each-Schleife wie folgt:

for (SomeObject obj : someObjects) {
   if (some_condition_met) {
      break; // or return obj
   }
}

Wie können wir mit der internen Iteration in einem Java 8 Lambda-Ausdruck break oder return verwenden wie:

someObjects.forEach(obj -> {
   //was soll hier getan werden?
})

3voto

tuga Punkte 331

Sie können das erreichen, indem Sie eine Kombination aus peek(..) und anyMatch(..) verwenden.

Unter Verwendung Ihres Beispiels:

someObjects.stream().peek(obj -> {

}).anyMatch(obj -> !);

Oder schreiben Sie einfach eine generische Hilfsmethode:

public static  void streamWhile(Stream stream, Predicate predicate, Consumer consumer) {
    stream.peek(consumer).anyMatch(predicate.negate());
}

Und verwenden Sie sie dann so:

streamWhile(someObjects.stream(), obj -> , obj -> {

});

1voto

int valueToMatch = 7;
Stream.of(1,2,3,4,5,6,7,8).anyMatch(val->{
   boolean isMatch = val == valueToMatch;
   if(isMatch) {
      /*Mache was du willst...*/
       System.out.println(val);
   }
   return isMatch;
});

Es führt nur Operationen durch, wenn es eine Übereinstimmung findet, und nachdem es eine Übereinstimmung gefunden hat, stoppt es die Iteration.

1voto

Sam Deir Punkte 31

Sie würden dies mit .map verwenden und einen booleschen Wert zurückgeben, um einen Abbruch anzugeben

someObjects.map(obj -> {
   if (some_condition_met) {
      return true;
   }
   return false;    
}).filter(Boolean.booleanValue).findAny();

findAny() ist eine kurzschließende Terminaloperation, sodass der Moment, in dem der Filter ein Element passiert (true), findFirst die Operation abbricht.

Eine noch kürzere Operation wäre der Aufruf von anyMatch anstelle von map wie unten gezeigt:

someObjects.anyMatch(obj -> {
       if (some_condition_met) {
          return true;
       }
       return false;    
    });

da anyMatch auch eine kurzschließende Operation ist.

0voto

Thomas Decaux Punkte 19874

Wie wäre es mit diesem:

final BooleanWrapper bedingung = new BooleanWrapper();
einigeObjekte.forEach(obj -> {
   if (bedingung.ok()) {
     // IHR CODE zur Steuerung
     bedingung.stop();
   }
});

Wo BooleanWrapper eine Klasse ist, die Sie implementieren müssen, um den Ablauf zu steuern.

0voto

Sahil Punkte 53

Ich würde vorschlagen, anyMatch zu verwenden. Beispiel:-

return someObjects.stream().anyMatch(obj -> 
    some_condition_met;
);

Sie können diesen Beitrag zur Erläuterung von anyMatch konsultieren:- https://beginnersbook.com/2017/11/java-8-stream-anymatch-example/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X