Tuesday 9 August 2016

Don't forget String is immutable in Java

Generally we try to manipulate the String (in Java) as we manipulate std::string in C++. But String is immutable in Java.

Now consider a program where you may need to change all the space with some string literal as "#45", then to solve this problem in place we need to use the char array to store the string. Using the String will result creation of more that one copies of String ( or one copy of String and other char array).

Consider this program :


public class Four {
    
    public static void main(String []args)
    {
        String str = new String();
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        str = scanner.nextLine();
        Four obj = new Four();
        int len = str.length();
        str = obj.changedString(str, len);
        System.out.println("New String Formed : "+str);
        scanner.close();
    }
    
    public String changedString(String str, int len)
    {
        int sCount = 0;
        for(int i = 0; i < len; ++i)
        {
            if (str.charAt(i) == ' ')
                sCount++;
        }
        int newLen = (2*sCount) + len;
        
        char str2[] = new char[newLen+1];
        str2[newLen] = '\0';
        
        for (int i = len-1; i >= 0; i--) 
        {
            if (str.charAt(i) == ' ')
            {
                str2[newLen -1] = '0';
                str2[newLen -2] = '2';
                str2[newLen -3] = '%';
                newLen = newLen-3;
            }
            else
            {
                str2[newLen-1] = str.charAt(i);
                newLen = newLen - 1;
            }
        }
        return new String(str2);
    }
}


So this is not a in place algo. We need to use the char Array to make it in place.

Consider this program written in C++:


/*
program to replace all spaces in a string with '%20'. use inplace algo.
*/
#include<iostream>
#include<cstring>
int countSpaceLength(char *str, int len)
{
    int sCount = 0;
    for(int i = 0; i < len; ++i)
    {
        if(str[i] == ' ')
            sCount++;
    }
    return sCount;
}
int main()
{
    char str[500];
    std::cin.getline(str, sizeof(str));
    std::cout<<std::endl;
    int sLen = strlen(str);
    int sCount = countSpaceLength(str, sLen);
    int newStringLen = sLen + (2*sCount);
    str[newStringLen] = '\0';
    for(int i = sLen-1; i >= 0; --i)
    {
         if(str[i] == ' ')
         {
            str[newStringLen - 1] = '0';
            str[newStringLen - 2] = '2';
            str[newStringLen - 3] = '%';
            newStringLen -= 3;
         }
         else
         {
            str[newStringLen - 1] = str[i];
            newStringLen -= 1;
         }
    }
    std::cout<<"New String Formed "<<std::endl<<str<<std::endl;
    return 0;
}

We can some time use

String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);
Or we can use a StringBuilder:

StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');

System.out.println(myName);

Thanks

1 comment: