OpenJDK / lambda / lambda / jdk
changeset 7838:526131346981
Pattern.splitAsStream.
Contributed-by: Ben Evans <benjamin.john.evans@gmail.com>
author | psandoz |
---|---|
date | Mon, 08 Apr 2013 17:16:36 +0200 |
parents | 0309ea20fc21 |
children | 3d940b4308ee |
files | src/share/classes/java/util/regex/Pattern.java test-ng/tests/org/openjdk/tests/java/util/regex/PatternTest.java |
diffstat | 2 files changed, 202 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/regex/Pattern.java Mon Apr 08 16:05:54 2013 +0200 +++ b/src/share/classes/java/util/regex/Pattern.java Mon Apr 08 17:16:36 2013 +0200 @@ -30,10 +30,18 @@ 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.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.Streams; /** @@ -5741,4 +5749,93 @@ 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 -> this.matcher(s).find(); + } + + private static class MatcherIterator implements Iterator<String> { + private final Matcher curMatcher; + private final CharSequence input; + private int current = 0; + private String nextElement = null; + private boolean valueReady = false; + + MatcherIterator(CharSequence in, Matcher m) { + input = in; + curMatcher = m; + } + + public void accept(String t) { + valueReady = true; + nextElement = t; + } + + public String next() { + if (!valueReady && !hasNext()) + throw new NoSuchElementException(); + else { + valueReady = false; + return nextElement; + } + } + + public boolean hasNext() { + if (!valueReady) { + if (current == input.length()) return false; + + if (curMatcher.find()) { + nextElement = input.subSequence(current, curMatcher.start()).toString(); + current = curMatcher.end(); + valueReady = true; + } else { + nextElement = input.subSequence(current, input.length()).toString(); + current = input.length(); + valueReady = true; + } + } + return true; + } + } + + + /** + * 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. + * + * @see #split(CharSequence) + * + * @param input + * The character sequence to be split + * + * @return The stream of strings computed by splitting the input + * around matches of this pattern + * @since 1.8 + * + */ + public Stream<String> splitAsStream(final CharSequence input) { + return Streams.stream(Spliterators.spliteratorUnknownSize(new MatcherIterator(input, matcher(input)), + Spliterator.ORDERED | Spliterator.NONNULL)); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-ng/tests/org/openjdk/tests/java/util/regex/PatternTest.java Mon Apr 08 17:16:36 2013 +0200 @@ -0,0 +1,105 @@ +package org.openjdk.tests.java.util.regex; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Functions; +import java.util.function.Supplier; +import java.util.regex.Pattern; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; +import java.util.stream.StreamTestData; +import java.util.stream.Streams; + +import static java.util.stream.Collectors.toList; + +@Test +public class PatternTest extends OpTestCase { + + @DataProvider(name = "Stream<String>") + public static Object[][] makeStreamTestData() { + List<Object[]> data = new ArrayList<>(); + + String description = ""; + String input = "awgqwefg1fefw4vssv1vvv1"; + Pattern pattern = Pattern.compile("4"); + List<String> expected = new ArrayList<>(); + expected.add("awgqwefg1fefw"); + expected.add("vssv1vvv1"); + + // Must match the type signature of the consumer of this data, testStrings + // String, String, Pattern, List<String> + data.add(new Object[]{description, input, pattern, expected}); + + input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"; + pattern = Pattern.compile("\u00a3a"); + expected = new ArrayList<>(); + expected.add("afbfq"); + expected.add("bgwgb"); + expected.add("wngnwggw"); + expected.add(""); + expected.add("hjrnhneerh"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "awgqwefg1fefw4vssv1vvv1"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("awgqwefg"); + expected.add("fefw4vssv"); + expected.add("vvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("a\u4ebafg"); + expected.add("fefw\u4eba4\u9f9cvssv\u9f9c"); + expected.add("v\u672c\u672cvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u56da456\u56da7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23"); + expected.add("456"); + expected.add("7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23\u9f9c\u672c\u672c"); + expected.add("456"); + expected.add("\u9f9c\u672c7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = ""; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + + data.add(new Object[]{description, input, pattern, expected}); + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "Stream<String>") + public void testStrings(String description, String input, Pattern pattern, List<String> expected) { + Supplier<Stream<String>> ss = () -> pattern.splitAsStream(input); + withData(new StreamTestData.StreamSupplierData<>(description, ss)) + .stream(Functions.identity()).expectedResult(expected).exercise(); + } +}