Lambda-fied pattern matching

Paul Sandoz paul.sandoz at oracle.com
Thu Dec 4 15:32:30 UTC 2014


Hi,

Catching up on this.

This seems useful:

  Stream<MatchResult> Pattern.matchAsStream(...) 

MatchResult  stream elements need to be cloned via Matcher.toMatchResult.

The following is perhaps less useful though might be handy for some matcher updates before handing off to a stream:

  Stream<MatchResult> Pattern.match(...).stream()

The stream source implementation will need to check for co-omodification of the matcher.

I still think we need some point lamdification though because the Matcher.append* methods are stateful and don't play nicely with streams. So something like:

  String Matcher.replace(Function<MatchResult, String> f) 

is also useful (this was previously discussed a while back on lambda-dev).

Paul.

On Nov 20, 2014, at 12:10 AM, Remi Forax <forax at univ-mlv.fr> wrote:

> 
> On 11/19/2014 10:54 PM, Dan Smith wrote:
>> Working with the pattern matching API, I noticed that it could be made a lot less clumsy with some lambdafication.
>> 
>> Here's the status quo:
>> 
>> Pattern p = Pattern.compile("(\w)*, (\d)*, (\w)*");
>> for (String s : lines) {
>>     Matcher m = p.matcher(str);
>>     if (m.match(s)) {
>>         System.out.println(m.group(1));
>>     }
>> }
>> 
>> With a lambda-friendly API:
>> 
>> Pattern p = Pattern.compile("\d*, \d*, \d*");
>> for (String s : lines) {
>>     p.match(str, r -> System.out.println(r.group(1)));
>> }
>> 
>> The 'match' is declared as 'match(String, Consumer<MatchResult>)'.  You could argue that the functional interface should be a Function rather than a Consumer; whatever.
>> 
>> Could also do 'matchFirst', 'matchAll' -- the latter eliminates even more boilerplate.
>> 
>> If considered useful, this could be added to String too:
>> 
>> str.match("\d*, \d*, \d*", r -> System.out.println(r.group(1)));
>> 
>> Is this something that has been considered?  Should I file an RFE?
>> 
>> —Dan
> 
> While I agree that we could have a more lambda-ish API,
> I prefer having a method Pattern.matchAsStream that returns a Stream of MatchResult
> because its more flexible that the API you propose.
> It's also more coherent with the fact that there is already a method splitAsStream().
> 
> Pattern p = Pattern.compile("(\d)*, (\d)*, (\d)*");
> for (String s : lines) {
>  p.matchAsStream(line).forEach(r -> System.out.println(r.group(1)));
> }
> 
> 
> or written using flatMap()
> 
> Pattern p = Pattern.compile("(\d)*, (\d)*, (\d)*");
> lines.stream().flatMap(line -> p.matchAsStream(line)).map(r -> r.group(1)).forEach(System.out::println);
> 
> 
> and yes, please log a RFE.
> 
> Rémi
> 
> 
> 
> 




More information about the core-libs-dev mailing list