Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4074696
Votes 1
Synopsis In addition to java.lang.String.Trim, add ltrim() and rtrim()
Category java:classes_lang
Reported Against 1.1.2
Release Fixed
State 11-Closed, Will Not Fix, request for enhancement
Priority: 5-Very Low
Related Bugs
Submit Date 27-AUG-1997
Description



1/ Try to trim whitespace from only the right side of a
string.  This is useful for writing source code editors
where the left hand side whitespace is useful for indenting
the source code, but the right hand side needs none.

2/ java.lang.String.trim() trims both ends of whitespace

3/ What should occur is that java.lang.String.trim() should
use java.lang.String.ltrim() and java.lang.String.rtrim().


======================================================================
Posted Date : 2005-12-23 02:26:28.0

A suggested implementsion submitted by java.net user leouser follows:

A DESCRIPTION OF THE FIX :
ID: 4074696
JDK VERSION: jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin

NOTE: This RFE is closed because it was thought that the RFE was not compelling enough.  I am in disagreement with this and am sending this in.  If its 'closedness' is the final word on the matter I will accept this. :)

RATIONAL( embedded in test as well ):
/**
 * BUG/RFE ID: 4074696  add rtrim and ltrim
 * RATIONALE:
 * String has trim(), which is useful in many cases.  Yet it is common to
 * want to remove the whitespace from only one end of the String.
 * There does not appear an obvious way of acheiving this in the String interface
 * at this time.  The simplest one line solution Ive come up with is to do
 * replaceFirst targeting the whitespace of the end or start of the text.
 * This probably is not desirable in code that requires high performance.
 *
 * In Python with a string, you have strip which is equivilent with trim.
 * But in Python you also have rstrip and lstrip.  These three are simple
 * to remember and use.
 *
 * Hence comes rtrim and ltrim.  Their implementations are derived from trim.
 * This means that they follow the implementation of trim in their own
 * implementation.  Being able to work with the char array directly makes
 * their implementatins fairly simple.
 *
 * It should be noted that this BUG ID was closed because it the case was
 * not compelling enough for its addition to the API.  From my individual usage
 * standpoint rtrim and ltrim are compelling to be added.
 *
 * Ramifications of change:
 * 2 new methods added.
 * Does not alter any internals in the implementation, calling
 * rtrim and ltrim should be safe to call.
 * String is final, there will be no subclasses fo String out there.
 * To acheive a subclass or modification the user will need to use
 * an extralinguistic mechanism.  This violates the contract, let them suffer.
 * More work in keeping trim, rtrim and ltrim in sync implementation wise.
 * I believe it is desirable to use relatively the same code for each implementation.
 * Hence if trim is made more efficient, rtrim and ltrim may also gain.
 * But they too will need to be changed.  Given the shortness of these methods,
 * it is questionable that the syncronization process would be cumbersome.
 *
 * This java.lang.String  was modified against:
 * jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
 *
 * and also executed on a Suse Linux 7.3 distribution.
 *
 * Brian Harry
 *   xxxxx@xxxxx  
 * Dec 22, 2005
 *
 *
 */

UNIFIED DIFF:
--- /home/brihar/nstuff/java6/jdk1.6.0/java/lang/String.java	Thu Dec 15 02:16:40 2005
+++ /home/brihar/javarefs/java/lang/String.java	Thu Dec 22 10:33:57 2005
@@ -2545,6 +2545,87 @@
     }
 
     /**
+     * Returns a copy of the string, with trailing whitespace
+     * omitted.
+     * <p>
+     * If this <code>String</code> object represents an empty character
+     * sequence, or the last characters of character sequence
+     * represented by this <code>String</code> object both have codes
+     * greater than <code>'&#92;u0020'</code> (the space character), then a
+     * reference to this <code>String</code> object is returned.
+     * <p>
+     * Otherwise, if there is no character with a code greater than
+     * <code>'&#92;u0020'</code> in the string, then a new
+     * <code>String</code> object representing an empty string is created
+     * and returned.
+     * <p>
+     * Otherwise, let <i>m</i> be the index of the last character in the string whose code
+     * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
+     * object is created, representing the substring of this string that
+     * begins with the character at index <i>0</i> and ends with the
+     * character at index <i>m</i>-that is, the result of
+     * <code>this.substring( 0,&nbsp;<i>m</i>+1)</code>.
+     * <p>
+     * This method may be used to trim whitespace (as defined above) from
+     * the end of a string.
+     *
+     * @return  A copy of this string with trailing white
+     *          space removed, or this string if it has no
+     *          trailing white space.
+     */
+    public String rtrim(){
+
+	int off = offset;
+	int i = off + count - 1;
+	char[] val = value;
+
+	while(  i >= off  &&  val[ i ] <= ' '  ) i--;
+
+	return  i != off + count -1 ? substring( 0, i + 1 - off ): this;
+
+    }
+
+    /**
+     * Returns a copy of the string, with leading whitespace
+     * omitted.
+     * <p>
+     * If this <code>String</code> object represents an empty character
+     * sequence, or the leading characters of character sequence
+     * represented by this <code>String</code> object both have codes
+     * greater than <code>'&#92;u0020'</code> (the space character), then a
+     * reference to this <code>String</code> object is returned.
+     * <p>
+     * Otherwise, if there is no character with a code greater than
+     * <code>'&#92;u0020'</code> in the string, then a new
+     * <code>String</code> object representing an empty string is created
+     * and returned.
+     * <p>
+     * Otherwise, let <i>m</i> be the index of the starting character in the string whose code
+     * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
+     * object is created, representing the substring of this string that
+     * begins with the character at index <i>m</i>, the result of this
+     * <code>this.substring( <i>m</i> )</code>.
+     * <p>
+     * This method may be used to trim whitespace (as defined above) from
+     * the start of a string.
+     *
+     * @return  A copy of this string with leading white
+     *          space removed, or this string if it has no
+     *          trailing white space.
+     */
+    public String ltrim(){
+
+        int len = count;
+	int i = 0;
+	char[] val = value;
+
+	while(  i < len  && val[ i ] <= ' '  ) i++;
+
+        return i != 0 ? substring( i ): this;
+
+    }
+
+    /**
      * This object (which is already a string!) is itself returned.
      *
      * @return  the string itself.


JUnit TESTCASE :
import junit.framework.TestCase;
import junit.textui.TestRunner;
import static java.lang.System.out;

/**
 * BUG/RFE ID: 4074696  add rtrim and ltrim
 * RATIONALE:
 * String has trim(), which is useful in many cases.  Yet it is common to
 * want to remove the whitespace from only one end of the String.
 * There does not appear an obvious way of acheiving this in the String interface
 * at this time.  The simplest one line solution Ive come up with is to do
 * replaceFirst targeting the whitespace of the end or start of the text.
 * This probably is not desirable in code that requires high performance.
 *
 * In Python with a string, you have strip which is equivilent with trim.
 * But in Python you also have rstrip and lstrip.  These three are simple
 * to remember and use.
 *
 * Hence comes rtrim and ltrim.  Their implementations are derived from trim.
 * This means that they follow the implementation of trim in their own
 * implementation.  Being able to work with the char array directly makes
 * their implementatins fairly simple.
 *
 * It should be noted that this BUG ID was closed because it the case was
 * not compelling enough for its addition to the API.  From my individual usage
 * standpoint rtrim and ltrim are compelling to be added.
 *
 * Ramifications of change:
 * 2 new methods added.
 * Does not alter any internals in the implementation, calling
 * rtrim and ltrim should be safe to call.
 * String is final, there will be no subclasses fo String out there.
 * To acheive a subclass or modification the user will need to use
 * an extralinguistic mechanism.  This violates the contract, let them suffer.
 * More work in keeping trim, rtrim and ltrim in sync implementation wise.
 * I believe it is desirable to use relatively the same code for each implementation.
 * Hence if trim is made more efficient, rtrim and ltrim may also gain.
 * But they too will need to be changed.  Given the shortness of these methods,
 * it is questionable that the syncronization process would be cumbersome.
 *
 * This java.lang.String  was modified against:
 * jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
 *
 * and also executed on a Suse Linux 7.3 distribution.
 *
 * Brian Harry
 *   xxxxx@xxxxx  
 * Dec 22, 2005
 *
 *
 */
public class StringTrimTest extends TestCase{

    public StringTrimTest( String test ){
	super( test );
    }


    public void testRtrim(){
	
	out.println();
	out.println( "Testing rtrim. expecting one failure" );
	String test1 = "    GGGG    V    ";
	String shouldbe1 = "    GGGG    V";
	assertEquals( "RtrimTest not equal", test1.rtrim() , shouldbe1 );

	String test2 = "         ";
	String shouldbe2 = "";
	assertEquals( "RtrimTest2 not equal", test2.rtrim(), shouldbe2 );

	String test3 = "";
	String shouldbe3 = "";
	assertEquals( "RtrimTest3 not equal", test3.rtrim(), shouldbe3 );

	String test4 = "\t\t\t";
	String shouldbe4 = "";
	assertEquals( "RtrimTest4 not equal", test4.rtrim(), shouldbe4 );

	String test5 = "\t\t\t\t   ";
	String shouldbe5 = "";
	assertEquals( "RtrimTest5 not equal", test5.rtrim(), shouldbe5 );

	/// should always fail:
	out.println( "THIS NEXT TEST IN RTRIM SHOULD FAIL!" );
	String test6 = "\t\t\t    ";
	String shouldbe6 = "  ";
	assertEquals( "RtrimTest6 not equal", test6.rtrim(), shouldbe6 );

    }

    public void testLtrim(){
	
	out.println();
	out.println( "Testing ltrim. expecting one failure" );
	String test1 = "    GGGG    V    ";
	String shouldbe1 = "GGGG    V    ";
	assertEquals( "LtrimTest not equal", test1.ltrim() , shouldbe1 );

	String test2 = "         ";
	String shouldbe2 = "";
	assertEquals( "LtrimTest2 not equal", test2.ltrim(), shouldbe2 );

	String test3 = "";
	String shouldbe3 = "";
	assertEquals( "LtrimTest3 not equal", test3.ltrim(), shouldbe3 );

	String test4 = "\t\t\t";
	String shouldbe4 = "";
	assertEquals( "LtrimTest4 not equal", test4.ltrim(), shouldbe4 );

	String test5 = "\t\t\t\t   ";
	String shouldbe5 = "";
	assertEquals( "LtrimTest5 not equal", test5.ltrim(), shouldbe5 );

	/// should always fail:
	out.println( "THIS NEXT TEST IN LTRIM SHOULD FAIL!" );
	String test6 = "\t\t\t    ";
	String shouldbe6 = "  ";
	assertEquals( "LtrimTest6 not equal", test6.ltrim(), shouldbe6 );

    }


    public static void main( String[] args ){
	
	out.println( "Testing rtrim..." );
	TestRunner.run( new StringTrimTest( "testRtrim" ) );
	out.println( "Testing ltrim..." );
	TestRunner.run( new StringTrimTest( "testLtrim" ) );

    }


 }







FIX FOR BUG NUMBER:
4074696
Posted Date : 2005-12-23 02:26:28.0
Work Around




The only work around is to re-write the functionality of
java.lang.String.trim() in a utility class.
======================================================================
Evaluation
This is not compelling enough to add. You can write this yourself and get reasonable performance with a modern VM.
Contribution-forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=10639
Posted Date : 2005-12-23 02:26:28.0
Comments
  
  Include a link with my name & email   

Submitted On 26-SEP-2006
veejnas
I have a better version I think...

import java.util.regex.*;

public class BlankRemover
{

    /* remove leading whitespace */
    public static String ltrim(String source) {
        return source.replaceAll("^\\s+", "");
    }

    /* remove trailing whitespace */
    public static String rtrim(String source) {
        return source.replaceAll("\\s+$", "");
    }

    /* replace multiple whitespaces between words with single blank */
    public static String itrim(String source) {
        return source.replaceAll("\\b\\s{2,}\\b", " ");
    }

    /* remove all superfluous whitespaces in source string */
    public static String trim(String source) {
        return itrim(ltrim(rtrim(source)));
    }

    public static String lrtrim(String source){
        return ltrim(rtrim(source));
    }

    public static void main(String[] args){
        String oldStr =
         ">     <1-2-1-2-1-2-1-2-1-2-1-----2-1-2-1-2-1-2-1-2-1-2-1-2>   <";
        String newStr = oldStr.replaceAll("-", " ");
        System.out.println(newStr);
        System.out.println(ltrim(newStr));
        System.out.println(rtrim(newStr));
        System.out.println(itrim(newStr));
        System.out.println(lrtrim(newStr));
    }


}


Submitted On 14-APR-2008
Its good to have ltrim and rtrim as a method of String class. This will help a lot...


Submitted On 20-APR-2009
Demion
Please reopen this ticket!!!
Is not compelling enought to add?
So minimal effort why should it not be added?



PLEASE NOTE: JDK6 is formerly known as Project Mustang