RFR 8071479: Stream and lamdification improvements to j.u.regex.Matcher

Paul Sandoz paul.sandoz at oracle.com
Fri Feb 27 18:55:35 UTC 2015


On Feb 27, 2015, at 7:48 PM, Xueming Shen <xueming.shen at oracle.com> wrote:

> On 02/27/2015 10:34 AM, Paul Sandoz wrote:
>> On Feb 27, 2015, at 7:18 PM, Xueming Shen<xueming.shen at oracle.com>  wrote:
>> 
>>> Hi Paul,
>>> 
>>> 1133      * @param  replacer
>>> 1134      *         The function to be applied to the match result of this matcher
>>> 1135      *         that returns a replacement string.
>>> 1136      *
>>> 1137      *<p>   The function should not modify this matcher's state during
>>> 1138      *         replacement.  This method will, on a best-effort basis, throw a
>>> 1139      *         {@link java.util.ConcurrentModificationException} if such
>>> 1140      *         modification is detected.
>>> 1141      *
>>> 1142      *<p>   The state of the match result is guaranteed to be constant
>>> 1143      *         only for the duration of the function call and only if the
>>> 1144      *         function does not modify this matcher's state.
>>> 
>>> 
>>> 1151      * @throws ConcurrentModificationException if it is detected, on a
>>> 1152      *         best-effort basis, that the replacer function modified this
>>> 1153      *         matcher's state
>>> 
>>> 
>>> Just wonder from API point of view, in theory the replacer should not be able to modify
>>> this matcher's state via a MatchResult, it is the side-effect of our implementation detail
>>> that happens to return "this matcher" as a MatchResult. For example, it should be possible
>>> to simply return a wrapper MatchResult on top of this matcher to only expose the read-only
>>> MatchResult methods, so the "replacer" will never be possible to modify the "matcher".
>>> 
>> It's not really about casting a MatchResult to Matcher it's about the function capturing the Matcher instance and operating on it.
>> 
> 
> The "replacer" does not have an explicit reference to the matcher...

Correct, just like a Consumer does not have an Iterable with Iterable.forEach.


> and
> from the implementation it is not really about the "replacer" to change the
> state of the matcher, but the matcher's state gets changed during "replacing"?

It's both, A function could do something silly, such as:

 Matcher m = ...
 m.replaceAll(mr -> { 
    m.find(); // bad
    // mr state is now messed up
    return mr.group();
 });


 List l = ...
 m.replaceAll(mr -> { 
  l.add(mr); // bad, mr escapes
  return mr.group();
 });


> it might be more clear/obvious to move those warning notes up to the method
> doc as "the matcher state should not be updated/changed during the replaceAll
> is invoked..."?
> 

Moving them up would be clearer, i will do that.

What about a light wright immutable MatchResult? is that possible?

Paul.




More information about the core-libs-dev mailing list