Java String, StringBuilder, Arrays, and ArrayList code and rules

String class


String s1 = new String("Hello");
String s2 = new String("Hello");   //Using the new operator means these are separate objects

System.out.println(s1 == s2);  // print false - because you are comparing the objects addresses

String s3 = "Goodbye";
String s4 = "Goodbye";

System.out.println(s3 == s4); // prints true - s3 and s4 are referring the same object, as they have the same sequence of characters. s4 is pointing to the same object as s3 (s3 created the object)

String m1 = "morning";
System.out.println("morning" == m1);   // prints true, referring to the same object

String m2 = new String("morning");
System.out.println("morning" == m2);   // prints false, different objects

String has overloaded constructors!


String s1 = new String("hello");

char[] c1 = new char[] {'H','e','l','l','o'};
String s2 = new String(c1);

StringBuilder sb1 = new StringBuilder("hello");
String s3 = new String(sb1);

StringBuffer sbf1 = new StringBuffer("hello");
String s4 = new String(sbf1);

//A literal value for a String is null

String s5 = null;

To recap String objects created versus references, let me show you where String objects are created


String s1 = new String("a string");  //object created
String s2 = "a string";              //object created
System.out.println("a string");      //reference 
System.out.println("different string");  //object created
System.out.println("different string" == "A string") //references (different string) and create (A string)
String different_string = new String("a string");  //object created

//This creates a total of five objects

Strings are immutable

Once created they can never be modified. String uses a char[] array to store the value “hello”.


String exampleValue = "hello";

//This is stored as a char[] e.g.

char[] exampleValue = new char[]{'h','e','l','l','o'};

It uses a final variable to store the value. This variable is private, meaning all methods of String appear to modify the string but in fact return a new String.

Methods of String
String example = new String("Hello World");

//charAt(int index)
System.out.println(example.charAt(0));   //returns H
System.out.println(example.charAt(2));   //returns l

//indexOf(char or String)
System.out.println(example.indexOf('W'));  //6
System.out.println(example.indexOf("rl")); //8 - start of rl
System.out.println(example.indexOf("z"));  //-1 - not there
System.out.println(example.indexOf('l'));  //2 first occurrence of l

//substring(int start position, [int length])

System.out.println(example.substring(6)); //World
System.out.println(example.substring(0,5)); //Hello
//NB: substring does not include the character at the end of the string

//trim()

String trimExample = new String("  Hello World  ");
System.out.println(":"+trimExample+":");          //returns - :  Hello World  :
System.out.println(":"+trimExample.trim()+":");   //returns - :Hello World:

//replace(char, char) or replace(String, String)

System.out.println(example.replace('o','P');            //returns - HellP WPrld
System.out.println(example.replace("Hello","GOODBYE");  //returns - GOODBYE World

//length()

System.out.println(example.length()); //returns - 11 (remember length-1 gives you the position

//startsWith() and endsWith()
//startsWith(String, [int position])

System.out.println(example.startsWith("H");   //return true
System.out.println(example.startsWith("o",4); //returns true

System.out.println(example.endsWith("d"));     //returns true
System.out.println(example.endsWith("worlD")); //returns false

//Methods can be chained together, when this is the case they are evaluated left to right

System.out.println(example.replace(' ','X').substring(0,5)); //returns Hello
System.out.println(example.replace(' ','Y').substring(5));   //returns YWorld

//Nasty one!!!

System.out.println(example.substring(0,2).startsWith('H'));  //this will not compile!!!!

System.out.println(example.substring(0,2).startsWith("H")); //this returns true!!!!

String concatenation and Equality

int intValue1 = 10;
int intValue2 = 20;

String strValue1 = "abcde";

String strValue2 = intValue1 + intValue2 + strValue1;  //evaluation is from left to right, so adds then concatenates

System.out.println(strValue2);  //returns 30abcde

String strValue3 = strValue1 + intValue1 + intValue2;

System.out.println(strValue3);   // returns abcde1020

String strValue4 = strValue1 + (intValue1 + intValue2);

System.out.println(strValue4);   // returns abcde30

//then there is the += to concatenate

String example2 = "Hello";

example2 += " world";

String example3 = null;
example3 += "example3";
System.out.println(example3); //returns nullexample3

For equality, lets look at the equals method from the class String

public boolean equals(Object anObject) {
    if (this == anObject) {     //if the objects are the same, then return ture
        return true;
    }
    
    if (anObject instanceof String) {               //Object is a string
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {   //checks if the length of the string in the two objects are the same
             char v1[] = value;
             char v2[] = anotherString.value;
             int i = offset;
             int j = anotherString.offset;
             while (n-- != 0) {              //Iterate through each string comparing char by char
                  if (v1[i++] != v2[j++])
                  return false;              //If one does not match the other then false
             }
             return true;                    //If both match then true
     }
     return false;
}

Quite interesting, lets look at some examples:

String example1 = new String("Hello");
String example2 = new String("Hello");

System.out.println(example1.equals(example2));  // returns true

System.out.println(example1 == example2);       // return false - they are two different objects
System.out.println(example1 != example2);       // return true - they are two different objects


String example3 = "Goodbye";
String example4 = "Goodbye";

System.out.println(example3.equals(example4));  // returns true

System.out.println(example3 == example4);       // returns true - they are the same objects (reference!)

//== compares reference objects
//equals compares String values

StringBuilder

Creating StringBuilder:

StringBuilder sb1 = new StringBuilder();

StringBuilder sb2 = new StringBuilder(sb1); //Constructor takes StringBuilder object (default length is 16)

StringBuilder sb3 = new StringBuilder(100); //Constructor takes length of String

StringBuilder sb4 = new StringBuilder(“Hello World”); //Constructor takes String (length is String + 16)
[/code]

Methods of StringBuilder

//APPEND() - accepts String, char array and Object
StringBuilder sbExample = new StringBuilder();
sbExample.append(true);
sbExample.append(100);
sbExample.append('b');
sbExample.append(39.99);
sbExample.append("Hello");

System.out.println(sbExample);  //returns true100b39.99Hello

char[] c = {'H','e','l','l','o',' ','W','o','r','l','d'};
sbExample.append(c,5,6);         //takes char array, start pos, and length
System.out.println(sbExample);  //returns true100b39.99Hello World

//Remember my class Example? Well it is mentioned on another posting, a simple class

sbExample.append(new Example());  //Appends this object to the stringbuilder object

The stringbuilder append method will call the .toString() method on the object, if you have not overwritten this (as in this case) it use the default implementation.

Example of the append code:

public AbstractStringBuilder append(boolean b) {
if (b) {
int newCount = count + 4; //adds 4 (length of “true”) to count – which is the number of characters held in the StringBuilder object
if (newCount > value.length) expandCapacity(newCount); //If the array is not long enough then it expands it

value[count++] = ‘t’;
value[count++] = ‘r’;
value[count++] = ‘u’;
value[count++] = ‘e’;
}
else {

}
return this;
}
[/code]

Next up is Insert.

StringBuilder example = new StringBuilder("bot");

example.insert("a",2);    //inserts the a before the t which is at position 2

System.out.println(example); //returns boat

You can also insert strings, and substrings of strings

StringBuilder example2 = new StringBuilder("Hello my friend");

char[] value = new char[]{'G','o','o','d','b','y','e',' ','w','o','r','l','d'};

example2.insert(5,value,7,6);

System.out.println(example2); // returns Hello world my friend

How about Deleting, persisting example2


example2.delete(5,11);   //5 is the start position, 11 is the length (6) added onto the start position
System.out.println(example2);

There is NO TRIM() method with StringBuilder

reverse()

Lets use a palindrome to demonstrate reverse 🙂 I mean, it is the best way to see it no?

StringBuilder palinDrome = "Man o nam";

palinDrome.reverse();

System.out.println(palinDrome); //return man o naM

replace()

Replaces a sequence of characters based on their position, with another String.


StringBuilder example = new StringBuilder("Hello my good friend");

example.replace(6,20,"World");   //where 6 is the start position, and 20 is the end position, and World is the text to replace that space

System.out.println(example);  //returns Hello World

subSequence()

Returns a CharSequence, which can easily be cast as a String if you want of the String in the StringBuilder


StringBuilder exampleSubSeq = new StringBuilder("0123456789");
CharSequence subr = exampleSubSeq.subSequence(5,8);     //start position is 5 and end position is 8 (everything before the end position)
System.out.println(subr);                               //returns 567
System.out.println(exampleSubSeq);                      //returns 0123456789

Arrays

What is an Array?

A collection of primitive types, and/or a collection of objects.


int primitiveArray[] = new int[] {1,2,3,4};
String objectArray[] = new String[] {"Hello", "World", "Goodbye", "all"};

Declaring arrays

int primitiveArray[];

int[] primitiveArray;  //Both of these are the same

int[] primitiveArray[]; //is the same as:
int[][] primitiveArray; //which is the same as:
int primitiveArray[][]; //These are multi-dimensional arrays

//You cannot define the size of the array in declaration
int primitiveArray[2];
int[3] primitiveArray;
int[4] primitiveArray[4];
//None of the above will compile

Array allocation

This is when specify the size of the array, please remember the size cannot change!!

int primitiveArray[];
String multiDArray[][];

primitiveArray = new int[100];
multiDArray = new String[5][5];

//The following are incorrect and will not compile
primitiveArray = new int[];
//or
primitiveArray[200] = new int;

//You can pass in variables for array allocation

int i = 100, j = 20;
String objectArray[] = new String[i*j]; //an array with 2000 elements

String objectArray[] = new String[Math.min(i,j)]; //an array of 20 elements

//Multi-dimensional arrays

int[] multi[];
multi = new int[100][];   //This is fine - in the first bracket

multi = new int[][100];   //This is not fine, it will not compile

Array Initialisation

Arrays can be initialised directly or through a loop.


String[] stringArray = new String[4];

for (int i = 0; i < stringArray.length; i++) {
    stringArray[i] = "Hello " + i;
}

//alternatively, you can set each value - in this instance the Hello string are overwritten

stringArray[0] = "goodbye";
stringArray[1] = "fairwell";
stringArray[2] = "see ya";
stringArray[3] = "ciao";

// the following will compile but generate a runtime exception

stringArray[4] = "oh dear";

// code will fail to compile if you don't pass in a char, byte, short or int

// You can combine all three, declaration, allocation, and initialisation e.g.

String[] strArray = {"a","b","c"}; //declares an array of size 3 with the values. NB no need for new operator
//You can use new, but you can't specify the size as well
String[] strArray = new String[]{"a","b","c"}; //fine
String[] strArray = new String[3]{"a","b","c"}; //fails to compile

//the following does not compile
String[] strArray;
strArray = {"a","b"};

//You need a new
String[] strArray;
strArray = new String[]{"a","b"};

Asymmetrical multidimensional arrays, are multidimensional arrays which are not symmetrical – no surprise really. What does this mean?

String multiAsymArr[][] = new String[][] {
              {"1","2"},
              null,
              {"a","b","c"},
              {"Z","Y",null,"x"},
       };

//note the above does not have the same number of columns
Interface, abstract, and object class arrays

You can define an array type as an interface, abstract class, or a object class.


interface exampleInterface { }
class ExampleClass1 implements exampleInterface {}
class ExampleClass2 implements exampleInterface {}

...

exampleInterface[] exampleArray = new exampleInterface[] {
                                              new ExampleClass1(),
                                              new ExampleClass2(),
                                              null
                                       };

//This array can hold objects which implement the interface or nulls

For Abstract class it is the same as interface, create the abstractclass. Create an array of the type the same as the abstract class and then it can hold objects which extend the abstract class or nulls.

Finally Objects. Well every object extends Object, so an array of Object can hold any Object:

interface exampleInterface { }
class ExampleClass1 implements exampleInterface { }
abstract class exampleAbstract{ }
class ExampleClass3 extends exampleAbstract{ }

...

Object[] objectArrayExample = new Object[] {
                             new ExampleClass1(),
                             new ExampleClass3(),
                             new java.util.Date(),
                             new String("hello world"),
                             null,
                             new Integer[10]
                     };

//As you can see an Object array can hold all different types of objects - including null.

To determine the number of elements in an array, use the method length. String has the method length() which returns the length of the string value.

ArrayList

Easier to use than an array. It automatically increases/decreases it’s size (unlike an Array). You don’t have to specify the initial size of the ArrayList. Some further pointers

  • null values can be added
  • interface List implemented
  • operators add, modify, and delete implemented
  • holds duplicate values
  • maintains order of values inserted
  • To iterate over an ArrayList you can use Iterator or ListIterator
  • Supports generics
  • declaring
    //you need to import ArrayList!!!!
    import java.util.ArrayList;
    
    public class ExampleCreateArrayList {
          public static void main(String[] args) {
                 ArrayList<String> example = new ArrayList<String>();
                 //As of Java version 7 you can create an arraylist like so:
                 ArrayList<String> example = new ArrayList<>();  //note the removal of String? Only Java 7 and higher
          }
    }
    //The initial size of an ArrayList is 10
    
    Adding elements

    We will stick with example now that it has been created as a ArrayList of String:

    //already done this
    //ArrayList<String> example = new ArrayList<String>();
    
    example.add("Hello");
    example.add("world");
    example.add("how");
    example.add("are");
    example.add("you");
    //all fine and dandy.
    //however we can add a value at a specified position.....
    example.add(3,"this is position three");
    
    //Accessing elements in an array is done via the enhanced for loop
    
    for (String element : example) {
         System.out.println(element);
    }
    
    /*This will output
    Hello
    world
    how
    this is position three
    are 
    you
    */
    
    //You can also use a ListIterator to access the elements
    ListIterator<String> exampleIterator = example.listIterator();
    
    while(exampleIterator.hasNext()) {
        System.out.println(exampleIterator.next());
    }
    
    

    NB: An Iterator or ListIterator, allows you to remove elements as you iterate over – this is not possible using a enhanced for loop.

    Modifying values
    import java.util.ArrayList;
    public class ModifyArrayListExample {
        public static void main(String[] args) {
            //So what we are going to do is create an arraylist, and then modify each value
            //rather than String, we will use StringBuilder as Strings are immutable
    
            ArrayList<StringBuilder> examArrList = new ArrayList<StringBuilder>();
            examArrList.add(new StringBuilder("First"));
            examArrList.add(new StringBuilder("Second"));
            examArrList.add(new StringBuilder("Third"));
    
            for (StringBuilder element : examArrList) {
                  element.append(" "+element.length());
            }
    
    
            //Now lets have a look at what we have done
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            /*
                 First 5
                 Second 6
                 Third 5           
            */
    
            //Another nice little one.... You can replace/change a value:
            examArrList.set(2,new StringBuilder("This is position two!"));
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            /*
                 First 5
                 Second 6
                 This is position two!
            */
    
        }
    }
    
    Removing elements

    There are two ways to remove elements:

  • remove(int index)
  • remove(Object o) — Only the first occurrence of the object
  • Lets continue with the example above.

    
            //In the first instance lets remove an entry....
            examArrList.remove(2);
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            StringBuilder exampleSB1 = new StringBuilder("example StringBuilder object");
    
            examArrList.add(exampleSB1);
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
            
            examArrList.remove(exampleSB1);
    
            for (StringBuilder element : examArrList) {
                  System.out.println(element);
            }
    
            //The new string is no longer in the list
    
    

    More methods to look at are

  • addAll(Collection c) – appends the collection to the end of the list
  • addAll(int index, Collection c) – appends all of the elements from the collection from position index to the end of the list
  • You can clear down your arraylist with the method .clear()

    
    ArrayList<String> example = new ArrayList<String>();
    example.add("Hello");
    example.add("world");
    example.add("goodbye");
    example.add("my friend");
    
    String val1 = example.get(1);
    System.out.println(val1); // return world
    
    int arrSize = example.size();
    System.out.println(arrSize); //return the size of the arraylist 4
    
    

    Other methods which are quite interesting… contains, indexof and lastIndexOf.

    //Create a Example Car class
    class Car {
        String model;
        Car(String model) {
            this.model = model;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Car) {
                Car t = (Car)obj;
                boolean res = t.model.equals(this.model);
                return res;
            }
            else return false;
       }
    }
    
    public class Example {
        public static void main(String[] args) {
           ArrayList<Car> myArrayList = new ArrayList<Car>();
    
           Car c1 = new Car("316");
           Car c2 = new Car("Micra");
    
           myArrayList.add(c1);
           myArrayList.add(c2);
           myArrayList.add(c2);
    
           System.out.println(myArrayList.contains(new Car("316")); //returns true - this is because we have overridden equals
           System.out.println(myArrayList.contains(c1); //returns true
    
           System.out.println(myArrayList.indexOf(new Car("Micra"));  //return 1 - this is because we have overridden equals
           System.out.println(myArrayList.indexOf(c2));  //returns 1
    
           System.out.println(MyArrayList.lastIndexOf(new Car("Micra"));  //returns 2 - this is because we have overridden equals
           System.out.println(MyArrayList.lastIndexOf(c2)); //returns 2
      }
    }
    

    You can clone an ArrayList, as well as return a Array of an ArrayList. Below is an example showing both the toArray in action and noting how referencing an object can come into play.

    import java.util.ArrayList;
    
    class ExampleArray {
    
    	static ArrayList als; // = new ArrayList();
    	static ArrayList alsb; // = new ArrayList();		
    	static String[] sarr;
    	static StringBuilder[] sbarr;
    
    	public static void displayAL() {
    		System.out.println("Displaying Array Lists");
    		
    		for (String val: als)
    			System.out.println(val);
    			
    		for (StringBuilder val: alsb)
    			System.out.println(val);	
    	}
    	
    	public static void displayA() {
    		System.out.println("Displaying Arrays");
    		
    		for (int i = 0; i &lt; sarr.length; i++) {
    			System.out.println(sarr[i]);
    		}
    
    		for (int i = 0; i &lt; sbarr.length; i++) {
    			System.out.println(sbarr[i]);
    		}	
    	}
    
    	public static void main(String[] args) {
    		
    		
    		String s1 = new String(&quot;hello&quot;);
    		String s2 = new String(&quot;there&quot;);
    		
    		StringBuilder sb1 = new StringBuilder(&quot;good&quot;);
    		StringBuilder sb2 = new StringBuilder(&quot;day&quot;);
    		
    		als = new ArrayList();
    		alsb = new ArrayList();
    		
    		als.add(s1);
    		als.add(s2);
    		
    		alsb.add(sb1);
    		alsb.add(sb2);
    		
    		System.out.println("first run through");
    		displayAL();
    		
    		sarr = new String[als.size()];	
    
    		sarr = als.toArray(sarr);
    
    		sbarr = new StringBuilder[alsb.size()];
    
    		sbarr = alsb.toArray(sbarr);
    		
    		System.out.println("second run through");
    		displayAL();
    		displayA();
    		
    		System.out.print("Changed s1 from "+s1);
    		
    		
    		s1 = "zzzzz";
    		
    		
    		System.out.println(" to "+s1);
    		System.out.println("s1 is in Array List and String Array");
    		System.out.print("changed sb1 from "+sb1);
    		
    		
    		sb1.append(" my dear old ");
    		
    		
    		System.out.println(" to "+sb1);
    		System.out.println("sb1 is in Array List and String Array - what will we see?");
    		
    		System.out.println("third run through");
    		displayAL();
    		displayA();
    	}
    }
    

    The output from this is:

    first run through
    Displaying Array Lists
    hello
    there
    good
    day
    second run through
    Displaying Array Lists
    hello
    there
    good
    day
    Displaying Arrays
    hello
    there
    good
    day
    Changed s1 from hello to zzzzz
    s1 is in Array List and String Array
    changed sb1 from good to good my dear old
    sb1 is in Array List and String Array – what will we see?
    third run through
    Displaying Array Lists
    hello
    there
    good my dear old
    day
    Displaying Arrays
    hello
    there
    good my dear old
    day

    NB: how the change to the StringBuilder variable is reflected in both the ArrayList and the Array, this is because both the ArrayList and Array are holding references to the object.

    Equals, how objects are compared

    Let’s take an example of expanding the functionality of the equals methodology.

    import java.util.Date;
    import java.text.DateFormat;
    import java.util.Locale;
    import java.util.ArrayList;
    
    class ExampleEquals {
    	private String name;
    	private Date dob;
    	
    	ExampleEquals(String n, Date b) {
    		name = n;
    		dob = b;
    	}
    	
    	public String getName() {
    		return name;
    	}
    	
    	public Date getDOB() {
    		return dob;
    	}
    	
    	public boolean equals(Object o) {	   //NB: The equals method accepts a Object, not a ExampleEquals.
    		if (o instanceof ExampleEquals) {  //NB: You then evaluate the object to see if it is of the instance you want
    			ExampleEquals t = (ExampleEquals)o;  //NB: Then you can instantiate it
    			return (name.equals(t.getName()) && dob.equals(t.getDOB()));
    		}
    		
    		return false;
    	}
    }
    
    class TestExampleEquals {
    	public static void main(String args[]) throws Exception {
    
    		DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.UK);
    		
    		ExampleEquals e1 = new ExampleEquals("test", df.parse("25/12/1950"));
    		
    		ExampleEquals e2 = new ExampleEquals("tess", df.parse("25/12/1950"));
    		
    		ExampleEquals e3 = new ExampleEquals("test", df.parse("25/12/1950"));
    		
    		System.out.println("e1 compared to e2 == "+e1.equals(e2));
    		System.out.println("e2 compared to e3 == "+e2.equals(e3));
    		System.out.println("e3 compared to e1 == "+e3.equals(e1));
    		
    		//As you can see, comparing these objects uses our definition of the equals method
    		
    		//Lets us throw an ArrayList into the mix
    		
    		ArrayList<ExampleEquals> al = new ArrayList<ExampleEquals>();
    		al.add(e1);
    		al.add(e2);
    		al.add(e3);
    		
    		ExampleEquals e4 = new ExampleEquals("tess", df.parse("25/12/1950"));
    		
    		System.out.println("ArrayList contains e2 == "+al.contains(e2));
    		
    		System.out.println("ArrayList contains e4 == "+al.contains(e4));
    		
    	}
    }
    

    Output from this is:

    e1 compared to e2 == false
    e2 compared to e3 == false
    e3 compared to e1 == true
    ArrayList contains e2 == true
    ArrayList contains e4 == true

    Always be sure the equals takes an Object and not the actual class.

    The equals contract:

  • It is reflexive – any non-null reference value x, x.equals(x) should return true;
  • It is symmetric – any non-null reference value x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive – any non-null reference value x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent – any non-null reference value x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals() comparisons on the objects is modified.
  • for any non-null reference value x, x.equals(null) should return false.
  • The following violates the contract:

    public boolean equals(Object o) {
          return false;
    }
    

    A method which returns true (for equals) when passed a null violates this contract. The equals method cannot touch the values it is comparing, just compare them.

    reference: http://www.manning.com/gupta/

    Advertisements

    Tags: , , , , , ,

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s


    %d bloggers like this: