8012646: Pattern.splitAsStream
Reviewed-by: forax, plevart, alanb
Contributed-by: Ben Evans <benjamin.john.evans@gmail.com>, Paul Sandoz <paul.sandoz@oracle.com>
--- a/jdk/src/share/classes/java/util/regex/Pattern.java Thu May 09 12:00:46 2013 -0700
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java Wed May 01 18:40:31 2013 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,19 @@
package java.util.regex;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.text.CharacterIterator;
import java.text.Normalizer;
import java.util.Locale;
+import java.util.Iterator;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Arrays;
+import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
@@ -5742,4 +5746,83 @@
return Character.isMirrored(ch);}});
}
}
+
+ /**
+ * Creates a predicate which can be used to match a string.
+ *
+ * @return The predicate which can be used for matching on a string
+ * @since 1.8
+ */
+ public Predicate<String> asPredicate() {
+ return s -> matcher(s).find();
+ }
+
+ /**
+ * Creates a stream from the given input sequence around matches of this
+ * pattern.
+ *
+ * <p> The stream returned by this method contains each substring of the
+ * input sequence that is terminated by another subsequence that matches
+ * this pattern or is terminated by the end of the input sequence. The
+ * substrings in the stream are in the order in which they occur in the
+ * input.
+ *
+ * <p> If this pattern does not match any subsequence of the input then
+ * the resulting stream has just one element, namely the input sequence in
+ * string form.
+ *
+ * <p> If the input sequence is mutable, it must remain constant during the
+ * execution of the terminal stream operation. Otherwise, the result of the
+ * terminal stream operation is undefined.
+ *
+ * @param input
+ * The character sequence to be split
+ *
+ * @return The stream of strings computed by splitting the input
+ * around matches of this pattern
+ * @see #split(CharSequence)
+ * @since 1.8
+ */
+ public Stream<String> splitAsStream(final CharSequence input) {
+ class MatcherIterator implements Iterator<String> {
+ private final Matcher matcher;
+ // The start position of the next sub-sequence of input
+ // when current == input.length there are no more elements
+ private int current;
+ // null if the next element, if any, needs to obtained
+ private String nextElement;
+
+ MatcherIterator() {
+ this.matcher = matcher(input);
+ }
+
+ public String next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ String n = nextElement;
+ nextElement = null;
+ return n;
+ }
+
+ public boolean hasNext() {
+ if (nextElement != null)
+ return true;
+
+ if (current == input.length())
+ return false;
+
+ if (matcher.find()) {
+ nextElement = input.subSequence(current, matcher.start()).toString();
+ current = matcher.end();
+ } else {
+ nextElement = input.subSequence(current, input.length()).toString();
+ current = input.length();
+ }
+ return true;
+ }
+ }
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
+ new MatcherIterator(), Spliterator.ORDERED | Spliterator.NONNULL));
+ }
}
--- a/jdk/test/java/util/regex/RegExTest.java Thu May 09 12:00:46 2013 -0700
+++ b/jdk/test/java/util/regex/RegExTest.java Wed May 01 18:40:31 2013 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
* 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
- * 7067045 7014640 7189363 8007395 8013252 8013254
+ * 7067045 7014640 7189363 8007395 8013252 8013254 8012646
*/
import java.util.regex.*;
@@ -41,6 +41,7 @@
import java.io.*;
import java.util.*;
import java.nio.CharBuffer;
+import java.util.function.Predicate;
/**
* This is a test class created to check the operation of
@@ -145,6 +146,7 @@
linebreakTest();
branchTest();
groupCurlyNotFoundSuppTest();
+ patternAsPredicate();
if (failure) {
throw new
RuntimeException("RegExTest failed, 1st failure: " +
@@ -3997,4 +3999,19 @@
report("GroupCurly NotFoundSupp");
}
+ // This test is for 8012646
+ private static void patternAsPredicate() throws Exception {
+ Predicate<String> p = Pattern.compile("[a-z]+").asPredicate();
+
+ if (p.test("")) {
+ failCount++;
+ }
+ if (!p.test("word")) {
+ failCount++;
+ }
+ if (p.test("1234")) {
+ failCount++;
+ }
+ report("Pattern.asPredicate");
+ }
}