8145007: Pattern splitAsStream is not late binding as required by the specification
Reviewed-by: chegar, psandoz
Contributed-by: Tagir Valeev <amaembo@gmail.com>
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java Fri Dec 11 19:06:40 2015 -0800
+++ b/jdk/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/jdk/test/java/util/regex/PatternStreamTest.java Fri Dec 11 19:06:40 2015 -0800
+++ b/jdk/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");