From 3425cb637dc88fb93f7d1cd3fa72c152d1805ef8 Mon Sep 17 00:00:00 2001 From: psandoz Date: Fri, 20 Sep 2013 17:11:32 -0700 Subject: [PATCH] 8024341: j.u.regex.Pattern.splitAsStream() doesn't correspond to split() method if using an example from the spec Reviewed-by: alanb --- .../classes/java/util/regex/Pattern.java | 41 +++++++++++++++---- ...atternTest.java => PatternStreamTest.java} | 37 ++++++++++++++++- 2 files changed, 67 insertions(+), 11 deletions(-) rename test/java/util/regex/{PatternTest.java => PatternStreamTest.java} (82%) diff --git a/src/share/classes/java/util/regex/Pattern.java b/src/share/classes/java/util/regex/Pattern.java index 1dc72c10c..81ea7145a 100644 --- a/src/share/classes/java/util/regex/Pattern.java +++ b/src/share/classes/java/util/regex/Pattern.java @@ -5755,7 +5755,8 @@ NEXT: while (i <= last) { * 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. + * input. Trailing empty strings will be discarded and not encountered in + * the stream. * *

If this pattern does not match any subsequence of the input then * the resulting stream has just one element, namely the input sequence in @@ -5781,6 +5782,8 @@ NEXT: while (i <= last) { private int current; // null if the next element, if any, needs to obtained private String nextElement; + // > 0 if there are N next empty elements + private int emptyElementCount; MatcherIterator() { this.matcher = matcher(input); @@ -5790,26 +5793,46 @@ NEXT: while (i <= last) { if (!hasNext()) throw new NoSuchElementException(); - String n = nextElement; - nextElement = null; - return n; + if (emptyElementCount == 0) { + String n = nextElement; + nextElement = null; + return n; + } else { + emptyElementCount--; + return ""; + } } public boolean hasNext() { - if (nextElement != null) + if (nextElement != null || emptyElementCount > 0) return true; if (current == input.length()) return false; - if (matcher.find()) { + // Consume the next matching element + // Count sequence of matching empty elements + while (matcher.find()) { nextElement = input.subSequence(current, matcher.start()).toString(); current = matcher.end(); + if (!nextElement.isEmpty()) { + return true; + } else { + emptyElementCount++; + } + } + + // Consume last matching element + nextElement = input.subSequence(current, input.length()).toString(); + current = input.length(); + if (!nextElement.isEmpty()) { + return true; } else { - nextElement = input.subSequence(current, input.length()).toString(); - current = input.length(); + // Ignore a terminal sequence of matching empty elements + emptyElementCount = 0; + nextElement = null; + return false; } - return true; } } return StreamSupport.stream(Spliterators.spliteratorUnknownSize( diff --git a/test/java/util/regex/PatternTest.java b/test/java/util/regex/PatternStreamTest.java similarity index 82% rename from test/java/util/regex/PatternTest.java rename to test/java/util/regex/PatternStreamTest.java index aab17319a..374b62378 100644 --- a/test/java/util/regex/PatternTest.java +++ b/test/java/util/regex/PatternStreamTest.java @@ -23,10 +23,11 @@ /** * @test + * @bug 8016846 8024341 * @summary Unit tests for wrapping classes should delegate to default methods * @library ../stream/bootlib * @build java.util.stream.OpTestCase - * @run testng/othervm PatternTest + * @run testng/othervm PatternStreamTest */ import org.testng.annotations.DataProvider; @@ -42,7 +43,7 @@ import java.util.stream.Stream; import java.util.stream.TestData; @Test -public class PatternTest extends OpTestCase { +public class PatternStreamTest extends OpTestCase { @DataProvider(name = "Stream") public static Object[][] makeStreamTestData() { @@ -132,6 +133,38 @@ public class PatternTest extends OpTestCase { expected.add("different"); expected.add("separators"); + + description = "Repeated separators within and at end"; + input = "boo:and:foo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(":and:f"); + + + description = "Many repeated separators within and at end"; + input = "booooo:and:fooooo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":and:f"); + + description = "Many repeated separators before last match"; + input = "fooooo:"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("f"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":"); + data.add(new Object[] {description, input, pattern, expected}); return data.toArray(new Object[0][]); } -- GitLab