From 2a1775f3b1720236cb262f077bfec92d84465db8 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Sun, 13 Dec 2015 15:10:13 +0100 Subject: [PATCH] 8145007: Pattern splitAsStream is not late binding as required by the specification Reviewed-by: chegar, psandoz --- .../classes/java/util/regex/Pattern.java | 19 +++++++++---------- .../java/util/regex/PatternStreamTest.java | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java index e4f64db438a..3a6ac6f56a8 100644 --- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java @@ -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 @@ NEXT: while (i <= last) { */ public Stream splitAsStream(final CharSequence input) { class MatcherIterator implements Iterator { - 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 @@ NEXT: while (i <= last) { // > 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 @@ NEXT: while (i <= last) { } 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; diff --git a/jdk/test/java/util/regex/PatternStreamTest.java b/jdk/test/java/util/regex/PatternStreamTest.java index 349faad034a..1ac3bfd23e8 100644 --- a/jdk/test/java/util/regex/PatternStreamTest.java +++ b/jdk/test/java/util/regex/PatternStreamTest.java @@ -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.function.Supplier; 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 @@ public class PatternStreamTest extends OpTestCase { .exercise(); } + @Test + public void testLateBinding() { + Pattern pattern = Pattern.compile(","); + + StringBuilder sb = new StringBuilder("a,b,c,d,e"); + Stream 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");