8

It seems to me like ArrayList would be easier to use in nearly every scenario, it being very versatile. Is there an instance where a String[] would be used to store inputted data? If there is such a case, there must be a drawback in ArrayList, what would that be?

Only thing that comes to mind off the top of my head would be the variety of String methods like, substring() and split(), etc.

EDIT: New to StackOverflow as well. I apologize if this was a re-post. And thanks for the formatting.

Mizu
  • 113
  • 1
  • 5

6 Answers6

6

The short answer is: don't use an array, always use an array list. The only exception to this is if you absolutely need to control the amount of memory used or you have some specific performance constraint that only String[] can support.

In general, though, arrays are terrible to work with in an object oriented language, and almost always for the same reason: they make it very easy to break encapsulation. For example:

public class ExampleArray {
  private final String[] strings;

  public ExampleArray(String... strings) { this.strings = strings; }
  public String[] getStrings() { return strings; }
}

See any problems? Yea, you need to write getStrings() like this:

// ...
public String[] getStrings() { return Arrays.copy(strings); }
// ...

Otherwise, some caller can get a hold of your class' internal data and start modifying it. The only way to prevent this is to copy it every time a caller wants to see it. As opposed to the right way:

public class ExampleList {
  private final List<String> strings;

  // ...

  public List<String> getStrings() { return Collections.unmodifiableList(strings); }
}

Now you're not copying the data, you're just sticking it behind an API that doesn't allow changes. If you use the Guava Immutable* classes, even better.

severoon
  • 106
  • 1
4

Of course there are situations where you want to use String[] instead. If you know in advance how long the list will be, for instance, and the list might be large.

The main disadvantage of using ArrayList is that as the list grows, the array has to be reallocated, which isn't a free operation. You can mitigate that by preallocating it to be the size (or larger) you expect using the constructor that accepts an initialCapacity.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • It's the other way around - ArrayList is optimized for array growth, while manual reallocation of the entire String[] is not. – ignis Dec 14 '12 at 07:31
  • 2
    @ignis: `ArrayList` has to reallocate the backing array as it grows, it just does it for you under the covers. – T.J. Crowder Dec 14 '12 at 07:32
  • Does the reallocation cause any problems? or just bog down the program until it's done? – Mizu Dec 14 '12 at 07:39
  • @T.J.Crowder You can set the initial size of the ArrayList if you know you're going to need so much space. However I agree it's not as efficient (method calls, processing) for a fixed size object. – Philip Whitehouse Dec 14 '12 at 18:06
  • @PhilipWhitehouse: LOL You mean via the constructor I linked in my last sentence? ;-) – T.J. Crowder Dec 14 '12 at 18:09
  • @T.J.Crowder Ouch, my bad. Anyway the big problem with ArrayList growth is it's unpredictable. You can get sudden delays in operations because you happened to breach the threshold and have to reallocate a huge list - the same operation changes in complexity which is difficult to account for in performance analysis. – Philip Whitehouse Dec 14 '12 at 18:11
  • @PhilipWhitehouse: Yeah, exactly. And I don't believe the allocation algorithm is guaranteed, and so in theory could change between JVM releases (blech). AND the current implementation increases capacity by a full 50% each time you need more, which if you only needed a couple more slots is fairly expensive... :-) – T.J. Crowder Dec 14 '12 at 18:22
2

ArrayList is dynamic grow-able array in size, Where as string array or any type of array is static in size.

Obviously this dynamic grow features cause some cost, it reallocate the array with new size and copy element to it.

Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
2
  1. You can initialize Java arrays at compile time, like:

    String data[] = { "a", "b", "c" };

  2. In old versions of Java there was also the case for type safety. ArrayList elements had to be casted to the original type whereas Java arrays where type safe.

  3. Java arrays are part of the language and you will not be able to change them. ArrayList is part of the Java API. If you need (I do not recommend it though) you could substitute your own library to implement the ArrayList job.

kmkaplan
  • 18,655
  • 4
  • 51
  • 65
  • 2
    1. java.util.Arrays.asList("a", "b", "c"). 2. +1. – ignis Dec 14 '12 at 07:33
  • @ignis Not that it makes much difference in Java, but using java.util.Arrays.asList is runtime, not compile time. – kmkaplan Dec 14 '12 at 07:37
  • Your form is runtime as well: as a matter of fact, there's no "array" type in the class file [constant pool](http://en.wikipedia.org/wiki/Java_class_file#The_constant_pool). Being asList() a varargs, the compiler converts my form into your form under the hood, and then converts your form into instructions that initialize the array item by item. (Check out the source, asList() runs in O(1)). If, by "not that it makes much difference", you are referring to VM runtime bytecode optimization, well, I'm not sure they have yet invented any array-specific ones. – ignis Dec 14 '12 at 07:46
  • For point 3, I would +1 again if I could. It /is/ recommended to implement your own Collection or List or whatever, it's a design pattern but I cannot recall its name. See java.util.Collections for some examples. – ignis Dec 14 '12 at 07:51
1

Check out these questions asked by others in stackoverflow:

Array or List in Java. Which is faster?

Java Performance - ArrayLists versus Arrays for lots of fast reads

Community
  • 1
  • 1
Stanley
  • 5,057
  • 4
  • 34
  • 44
1

The only case that comes to my mind when array is used to hold some values is when there's a method taking variable number of arguments like:

void doSth(int i, String... strings){
 if(strings.length>0){
  //some stuff
 }

Otherwise I hardly ever intentionally create a situation, when array needs to be used.

wilu
  • 549
  • 1
  • 12
  • 26