I've rolled the code back. Now I'm thinking the following are
candidates to roll back to String:

    public static String stripAccents(CharSequence input) {
    public static String capitalize(CharSequence cs) {
    public static String uncapitalize(CharSequence cs) {

and the following are candidates to move to CharSequence:

    public static boolean equalsIgnoreCase(String str1, String str2) {
    public static int indexOf(String str, int searchChar) {
    public static int indexOf(String str, int searchChar, int startPos) {
    public static int indexOf(String str, String searchStr) {
    public static int indexOf(String str, String searchStr, int startPos) {
    public static int ordinalIndexOf(String str, String searchStr, int
ordinal) {
    public static int indexOfIgnoreCase(String str, String searchStr) {
    public static int indexOfIgnoreCase(String str, String searchStr,
int startPos) {
    public static int lastIndexOf(String str, int searchChar) {
    public static int lastIndexOf(String str, int searchChar, int startPos) {
    public static int lastIndexOf(String str, String searchStr) {
    public static int lastOrdinalIndexOf(String str, String searchStr,
int ordinal) {
    public static int lastIndexOf(String str, String searchStr, int startPos) {
    public static int lastIndexOfIgnoreCase(String str, String searchStr) {
    public static int lastIndexOfIgnoreCase(String str, String
searchStr, int startPos) {
    public static boolean contains(String str, int searchChar) {
    public static boolean contains(String str, String searchStr) {
    public static boolean containsIgnoreCase(String str, String searchStr) {
    public static boolean containsWhitespace(String str) {
    public static boolean containsAny(String cs, char[] searchChars) {
    public static boolean containsAny(String cs, String searchChars) {
    public static int indexOfAnyBut(String str, String searchChars) {
    public static int indexOfAny(String str, String[] searchStrs) {
    public static int lastIndexOfAny(String str, String[] searchStrs) {
    public static int countMatches(String str, String sub) {
    public static boolean startsWith(String str, String prefix) {
    public static boolean startsWithIgnoreCase(String str, String prefix) {
    public static boolean startsWithAny(String string, String...
searchStrings) {
    public static boolean endsWith(String str, String suffix) {
    public static boolean endsWithIgnoreCase(String str, String suffix) {
    public static boolean endsWithAny(String string, String... searchStrings) {

Basic rules being 'if String is returned, then String should be passed
in' and 'if other than String is returned, pass in CharSequence'.

Hen

On Sun, Apr 3, 2011 at 2:45 PM, Henri Yandell <flame...@gmail.com> wrote:
> Agreed (apologies for the delay; life got, and is going to remain, very busy).
>
> We should remove the CharSequence code I added. We should also review
> the first batch of CharSequence changes.
>
> I think it's fine to have this:
>
> public int length(CharSequence seq)
>
> I'll look into the removal if no one else gets to it - with a new baby
> in the house that's going to depend very much on how calm she is.
>
> Hen
>
> On Fri, Mar 18, 2011 at 1:21 AM, Stephen Colebourne
> <scolebou...@joda.org> wrote:
>> On 18 March 2011 03:56, Henri Yandell <flame...@gmail.com> 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 IMO.is StrBuilder, which is [lang] owned. That
>> is where all these utility methods go, Thus you can do:
>>
>> StrBuilder b = ...
>> b.setLowerCase()
>>
>> 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
>> Strings.
>>
>>> 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
>> choice.
>>
>> 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.
>>
>> Stephen
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>> For additional commands, e-mail: dev-h...@commons.apache.org
>>
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to