changeset 13333:809b13e8d211

8145007: Pattern splitAsStream is not late binding as required by the specification Reviewed-by: chegar, psandoz Contributed-by: Tagir Valeev <amaembo@gmail.com>
author psandoz
date Sun, 13 Dec 2015 15:10:13 +0100
parents db0148cc63a6
children bf153b12450b
files src/java.base/share/classes/java/util/regex/Pattern.java test/java/util/regex/PatternStreamTest.java
diffstat 2 files changed, 25 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Dec 11 19:06:40 2015 -0800
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Sun Dec 13 15:10:13 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -5814,7 +5814,7 @@
      */
     public Stream<String> splitAsStream(final CharSequence input) {
         class MatcherIterator implements Iterator<String> {
-            private final Matcher matcher;
+            private Matcher matcher;
             // The start position of the next sub-sequence of input
             // when current == input.length there are no more elements
             private int current;
@@ -5823,14 +5823,6 @@
             // > 0 if there are N next empty elements
             private int emptyElementCount;
 
-            MatcherIterator() {
-                this.matcher = matcher(input);
-                // If the input is an empty string then the result can only be a
-                // stream of the input.  Induce that by setting the empty
-                // element count to 1
-                this.emptyElementCount = input.length() == 0 ? 1 : 0;
-            }
-
             public String next() {
                 if (!hasNext())
                     throw new NoSuchElementException();
@@ -5846,6 +5838,13 @@
             }
 
             public boolean hasNext() {
+                if (matcher == null) {
+                    matcher = matcher(input);
+                    // If the input is an empty string then the result can only be a
+                    // stream of the input.  Induce that by setting the empty
+                    // element count to 1
+                    emptyElementCount = input.length() == 0 ? 1 : 0;
+                }
                 if (nextElement != null || emptyElementCount > 0)
                     return true;
 
--- a/test/java/util/regex/PatternStreamTest.java	Fri Dec 11 19:06:40 2015 -0800
+++ b/test/java/util/regex/PatternStreamTest.java	Sun Dec 13 15:10:13 2015 +0100
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8016846 8024341 8071479
+ * @bug 8016846 8024341 8071479 8145006
  * @summary Unit tests stream and lambda-based methods on Pattern and Matcher
  * @library ../stream/bootlib/java.base
  * @build java.util.stream.OpTestCase
@@ -42,6 +42,7 @@
 import java.util.regex.MatchResult;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
@@ -185,6 +186,20 @@
                 .exercise();
     }
 
+    @Test
+    public void testLateBinding() {
+        Pattern pattern = Pattern.compile(",");
+
+        StringBuilder sb = new StringBuilder("a,b,c,d,e");
+        Stream<String> stream = pattern.splitAsStream(sb);
+        sb.setLength(3);
+        assertEquals(Arrays.asList("a", "b"), stream.collect(Collectors.toList()));
+
+        stream = pattern.splitAsStream(sb);
+        sb.append(",f,g");
+        assertEquals(Arrays.asList("a", "b", "f", "g"), stream.collect(Collectors.toList()));
+    }
+
     public void testFailfastMatchResults() {
         Pattern p = Pattern.compile("X");
         Matcher m = p.matcher("XX");