An array is pretty much the same as in any other language, and ArrayList is a linked list (sort of a dynamic array).
It's (and most container classes) methods include:
add(Object o) //add element to rear of list
add(Object o, int i) //add element o at ith position
addAll(Container c) //add all elements in another container element
addAll(Object[] o) //add all objects in array
get(int i) //get object at ith position
remove(int i) //get object at ith position and remove it from the list
lot's more....look it up
The beauty is, you don't have to worry about the size, it is dynamic.
If you remove the ith element, the (i+1)th element becomes the ith and everything moves down (well it actually doesn't but it appears to to the user)
Not sure on the String/StringBuffer....I think the StringBuffer allows more manipulation and (if memory serves me correct) a StringBuffer is an actual object whereas a String just pretends to be. Specifically, if you try to manipulate a String you keep creating new Strings (of different lengths and with different values), while the StringBuffer actually manipulates the actual String you are playing wiht (someone will undoubtedly correct me if I'm wrong....)