commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen Colebourne <>
Subject Re: [lang] CharSequenceUtils resurrection? [Was: Remaining work]
Date Fri, 18 Mar 2011 08:21:33 GMT
On 18 March 2011 03:56, Henri Yandell <> wrote:
> Something occurred to me today. We're moving from String to
> CharSequence in the API, but not thinking of the use case.
> If I call:
>    StringUtils.toLowerCase(stringBuffer);
> I'd argue that the likely style would be to modify the object being
> passed in, not to return it (even if we could return a StringBuffer
> instead of a new String). More specifically, if the CharSequence is
> mutable, then mutate the passed in value, whereas if the CharSequence
> is immutable, return a new version.
> This makes me wonder if there's any value in moving to CharSequence.

As I've probably said before, I think that most people are looking for
a StringUtils operating on Strings and nulls. I personally never hold
CharSequence as a variable, although obviously I use StringBuffer,
StringBuilder and StrBuilder. But, I rarely have a CharSequence that
is null - it doesn't make that much sense to do so as mutable strings
are transient.

The significant class StrBuilder, which is [lang] owned. That
is where all these utility methods go, Thus you can do:

StrBuilder b = ...

If you need to operate on a StringBuffer or StringBuilder? Well,
don't! [lang] says use StrBuilder. That was the original design, and
frankly it still makes sense.

Perhaps this is harsh and there is a role for a helper class for other
CharSequence classes, but its one I personally would use rarely. Thats
because null is rarely the issue with CharSequences, and it can easily
be changed in most user code to a StrBuilder.

> a) For every method, once CharSequence is there, return null if its a
> known mutable and instead mutate the CharSequence.
Horrible API

> b) For every method, once CharSequence is there, return a new string
> AND for known mutables mutate the CharSequence.
Far from great (lots of code to create an abstraction that isn't abstract)

> c) Create a StringMutate class (by moving StringUtils) which modifies
> the passed in and known mutable subclasses of CharSequence, then put
> StringUtils on top of it and have it create a new StringBuilder each
> time and pass it down to the class (or classes) with the real code.
Well, you could consider StrBuilder to be a form of StringMutate I
suppose. But having StringUtils create and use a buffer for every
method is very poor for performance. The performance really matters
here, and thats why I think StringUtils should revert to solely

> I'm liking c). We could add a super class above StrBuilder -
> MutableCharSequence - and then implement three methods for every
> method in StringUtils to support the three big mutables
> (StringBuilder, StringBuffer + MutableCharSequence); or we could drop
> StringBuffer. That increases the size of the class to 13,000 lines :)
There are many ways to cut this, for example, StrBuilder could be
reworked to have the ability to update StringBuilder/StringBuffer:

StringBuffer buf = ...
StrBuilder view = StrBuilder.asViewOf(buf);
view.setLowerCase()  // updates view and buf

Internally, StrBuilder could
(a) hold an Object and have a low level mutation plugin for char[],
StringBuilder and StringBuffer
(b) StrBuilder could store a StringBuilder rather than a char[],
although I suspect that would hurt performance
(c) Every StrBuilder method could end with resetLinkedView(), which
would do buf.setLength(0);buf.append(toString()); Simple, but slow.

It depends if there is the desire to support
StringBuffer/StringBuilder or not.I suspect that (a) is the best

BTW, tearing CharSequence out of StringUtils sounds harsh. But I've
been forced to tear generics out of systems late in the day when I've
realised that they made the API worse not better. This seems like a
parallel case here - we've been making StringUtils more complex, and
its fundamentally not giving the desired benefits.


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message