From JavaProgramming
Arrays and strings in Java
Warning: There be dragons here... [I just refactored them away, hopefully I got them all]
Thanks, actually I meant that the topic itself is fraught with traps, pitfalls, and landmines. See JavaArraysBreakTypeSafety and JavaArraysShouldBeFirstClassObjects, for example.
Arrays
Arrays have constant size:
int arr[] = new int[3];If more space is needed at run time, a new array object must be created, and you must manually copy any data you still need from the old array.
Use collection classes, such as java.util.ArrayList for dynamic arrays.
int arr2[][] = new int[3][2];Array declarations may have the [] before or after the variable name:
int[] foo; int bar[];Arrays may be initialized in code:
int ages[] = { 3, 6, 7 };Multidimensional arrays may be non-rectangular:
int ragged[][] = { {1, 2}, {3, 4, 5}, {6} };Strings
The String class has no index-operator, use method charAt():
//char c = s[0]; // Index operator not supported char c = s.charAt(0); // OkThe + operator performs concatenation in expressions that have a String operand. Beyond this compiler-based "overloading", operator overloading is not supported in Java.
Thus, strings may be concatenated with other strings or expressions of other types:
String s = "number: " + 10;String concatenation with other object types implicitly invokes toString() on the operand.
Date d = new Date(); String s = "now: " + d;Prints something like: "now: Wed Jun 26 14:25:08 MDT 2002"
For Strings -- and indeed all object types -- the equality operator (==) tests for object identity, not lexical equivalence. Use equals() to test for lexical equivalence between strings, and use == only to test if two references point to the exact same string instance:
String s1 = "123", s2 = s1, s3 = new String(s1); System.out.println(s1 == s2); // prints true System.out.println(s1 == s3); // prints false System.out.println(s1.equals(s2)); // prints true System.out.println(s1.equals(s3)); // prints trueIt is possible to use the intern() function to use == for comparison: s1.equals(s2) if and only if s1.intern() == s2.intern(). Of course the gain is to store the result of s.intern(), and then get faster comparisons.
---------------------------
String s1 = "123", s2 = "123"; // boolean b = (s1 == s2); // Equality operator not supported [[wrong]] boolean b = s1.equals(s2); // OK!
---------------------------Conventional wisdom has advised to use StringBuffer profusely, however such advice is mostly outdated since current Java compilers will use StringBuffer in the generated code. The original exhange retained below tells most of the story, and I will return with more examples. The current compilers do a pretty good job on complex string expressions.
final long yarms = 3; String s = "There are " + 4 + " arms on the capital letter " + 'X' + " and " + " there are only " + yarms + " on the letter " + 'Y' + ".";becomes
String s = "There are 4 arms on the capital letter X and there are only 3 on the letter Y.";Don't trust me on this... use javap -c and see for yourself! (javap comes with your JDK.)
For me, the moral of the String/StringBuffer story is to be careful with performance advice from Java book authors. Most Java performance tricks fall out of date as the compilers approach professional quality and as the runtime environments improve. (In fact, some of the tricks that improved performance under earlier Java releases actually hinder performance under later versions of Java!)
---------------------------[original exchange on String and StringBuffer]]
String s = "abc"; s += "def";// Creating new String object Stringbuffer sb = "abc"; sb.append("def"); // StringBuffer object now contains "abcdef"
String s = "abc"; StringBuffer sb = new StringBuffer(s); sb.append("def"); s=sb.toString();
Here is a test program for trying out array and string functions: [Dragons remain]
/* TestString.java */ public class TestString { public static void main(String[] args) { int arr[] = new int[3]; arr[0] = 1; arr = new int[4];// Data lost on creation of a new array System.out.println("" + arr[0]); // Output = 0 String s = "123"; // if(s[0] == '1') // Index operator not supported if(s.charAt(0) == '1') // Ok, output: true System.out.println("true"); else System.out.println("false"); // or to a Java programmer: System.out.println(s.charAt(0) == '1'); :-) // Arithmetic operators supported for String s = "number: " + 10; // Implicit call to String() and Integer.toString() [actually, it gets folded together at compile time] System.out.println(s); // output: number: 10 s = Integer.toString(10); // Explicit conversion System.out.println(s); // output: 10 String s1 = "123", s2 = "123"; // [Grrrrowwl] // if(s1 == s2) System.out.println("true"); // Equality operator not supported // ["not supported" overstates things... "doesn't do what some might expect".] if(s1.equals(s2)) // Output: true System.out.println("true"); else System.out.println("false"); // Use StringBuffer for better performance [ummm...] s = "abc"; s += "def";// Creating new String object System.out.println(s); // output: abcdef StringBuffer sb = new StringBuffer("abc"); sb.append("def"); // StringBuffer object now contains "abcdef" System.out.println(sb); // output: abcdef } }
StringBuffer improves upon String when a loop comes into play.
String[] term = new String[1000]; for (int i = 0; i < term.length; ++i) { term[i] = "term " + i + ","; } // Now start timing. String stringConcatenation = ""; for (int i = 0; i < term.length; ++i) { stringConcatenation += term[i]; } // Compare to: StringBuffer stringBufferConcatenation = new StringBuffer(); for (int i = 0; i < term.length; ++i) { stringBufferConcatenation.append(term[i]); } String sbFinal = stringBufferConcatenation.toString();It would be a very sophisticated compiler that converted the String loop to the StringBuffer form. And, if the variables were attributes instead of method-local variables, it wouldn't even be correct, considering the possibilities of multi-threading. --EricJablow