Einfache Möglichkeit, eine Implementierung von java.util.stream.Stream zu erstellen

Motivation

Die typische Redewendung für die Verarbeitung von Teilzeichenfolgen, die einem regulären Ausdruck entsprechen, mit java.regex.Matcher lautet:

Pattern pattern = Pattern.compile("(cola)+");
Matcher matcher = pattern.matcher("cola, cola, I love cola.");
while (mather.find()) {
  // do something with the current match.
  System.err.println(matcher.group());
}

Wenn Sie nur eine schreibgeschützte Verarbeitung für das übereinstimmende Teil durchführen möchten, sollten Sie es als Stream-Verarbeitung schreiben können. So was.

Matcher matcher = pattern.matcher("cola, cola, I love cola.");
matcher.forEach(h -> System.err.println(h.group()); //h ist etwas, das eine Übereinstimmung darstellt (muss definiert werden)

Es war gut zu glauben, dass dies durch die Erstellung einer Implementierung von "java.util.stream.Stream" realisiert werden könnte, die "Matcher" umschließt. Die Implementierung ist jedoch schwierig, da zu viele Schnittstellen und Methoden vorhanden sind. https://docs.oracle.com/javase/jp/9/docs/api/java/util/stream/Stream.html Gibt es eine einfache Möglichkeit, "Stream" zu implementieren?

Nachtrag: Lösung für "Matcher"

Der ursprüngliche Artikel listete die allgemeinen Lösungen unten auf, aber für "Matcher" können Sie die vollständige Antwort erhalten, indem Sie "Matcher # results ()" von Java 9 verwenden. Die Implementierung dieser Methode implementiert genau das, was ich oben geschrieben habe.

Pattern pattern = Pattern.compile("(cola)+");
pattern.matcher("cola, cola, I love cola.").results()
    .forEach(x -> System.err.println(x.group()));

HINWEIS: Vielen Dank an @ saka1029 für den Hinweis. Im Folgenden finden Sie außerdem die allgemeine Methode, um etwas anderes als "Matcher" zu wiederholen.

Gemeinsame Lösung

Als Ergebnis einer kleinen Untersuchung wurde festgestellt, dass durch Kombinieren von "StreamSupport # stream" und "Spliterators # spliteratorUnknownSize" Folgendes geschrieben werden kann. Wie Sie sehen können, kann diese Methode nicht nur auf "Matcher" angewendet werden, sondern auch auf die Implementierung von "java.util.Iterator". Deshalb ist es so vielseitig, dass ich es mir notieren werde. [Ergänzung: Ich verstehe, dass dieses Beispiel alleine länger und komplizierter ist als der ursprüngliche Code :-)]

RegExTest.java


import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 
 */
public class RegExTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		
		final Pattern pattern = Pattern.compile("(cola)+");

		final Stream<Matcher> s = StreamSupport.stream(
			Spliterators.spliteratorUnknownSize(
				new Iterator<Matcher>() {
					final Matcher matcher = pattern.matcher("cola, cola, I love cola.");
					@Override
					public boolean hasNext() {
						return matcher.find();
					}
					@Override
					public Matcher next() {
						return matcher;
					}
				},
				Spliterator.NONNULL | Spliterator.IMMUTABLE),
			false);
		
		//Sie können es jetzt genauso verwenden wie das Beispiel am Anfang!
		s.forEach(m -> System.err.println(m.group()));
	}

}

Nachtrag: So vermeiden Sie die Implementierung von "java.util.Iterator"

@ saka1029 wies erneut auf die von Java9 von java.util.stream.Stream bereitgestellte Methode Stream # iterate hin. Mit api / java / util / stream / Stream.html # iterate (T, java.util.function.Predicate, java.util.function.UnaryOperator) ist es wunderschön, ohne Iterator wie unten gezeigt zu implementieren. Ich habe gelernt, dass ich schreiben kann. Vielen Dank, @ saka1029. Ich bin froh, dass Java9 diese neue Art des Schreibens bietet, denn es hätte viele andere Menschen als mich gegeben, die sich gewünscht hätten, ich könnte es so schreiben.

final Pattern pattern = Pattern.compile("(cola)+");
Stream.iterate(pattern.matcher("cola, cola, I love cola."), m -> m.find(), m -> m)
    .forEach(m -> System.out.println(m.group()));

Recommended Posts

Einfache Möglichkeit, eine Implementierung von java.util.stream.Stream zu erstellen
Einfache Möglichkeit, benutzerdefinierte JSP-Tags zu erstellen
Einfache Möglichkeit, ein eigenes Anwendungslogo zu erstellen (einfach mit Ihrem Smartphone)
Bearbeiten Sie Pixel, um ein Bild eines Mandelbrot-Sets zu erstellen
Einfach zu erstellende Verarbeitungsbibliothek
Einfache Implementierung des Durchsuchens von Android-Dateien
[Schienen] Einfache Möglichkeit, Spalten zu überprüfen
Einfache Möglichkeit zum Erstellen einer Zuordnungsklasse bei Verwendung der API
Einfache Möglichkeit, iOS-App-Symbole festzulegen
So verwischen Sie das Bild (super einfach)
Java-Implementierung zum Erstellen und Lösen von Labyrinthen
Konvertieren Sie ein Array von Zeichenfolgen in Zahlen
[Apache Camel] Einfacher Durchsatz in einem Protokoll ausgeben
Zusammenfassung zum Erstellen von selbst erstellten JSF-Tags
[Rails] Implementierung von "Benachrichtigung auf irgendeine Weise benachrichtigen"
Super einfache Möglichkeit, Enum mit JSP zu verwenden
Rails6.0 ~ So erstellen Sie eine umweltfreundliche Entwicklungsumgebung
So erstellen Sie ein Oleore-Zertifikat (SSL-Zertifikat, Selbstzertifikat)