8012646: Pattern.splitAsStream
authorpsandoz
Wed, 01 May 2013 18:40:31 +0200
changeset 17447 3031deba3fbe
parent 17446 0f1a66edc2ca
child 17449 93b0810b4d73
8012646: Pattern.splitAsStream Reviewed-by: forax, plevart, alanb Contributed-by: Ben Evans <benjamin.john.evans@gmail.com>, Paul Sandoz <paul.sandoz@oracle.com>
jdk/src/share/classes/java/util/regex/Pattern.java
jdk/test/java/util/regex/RegExTest.java
--- 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");
+    }
 }