356

I have the following code:

String[] where;
where.append(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.append(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Those two appends are not compiling. How would that work correctly?

Hasen
  • 11,710
  • 23
  • 77
  • 135
Pentium10
  • 204,586
  • 122
  • 423
  • 502
  • 7
    although this question has +10 years and it is important to compare the differences between lists and arrays, it's astonishing how deep I had to roll to find how to actually have a resulting array with a new element added, as OP originally asked for – rado Apr 30 '21 at 20:51

20 Answers20

462

The size of an array can't be modified. If you want a bigger array you have to instantiate a new one.

A better solution would be to use an ArrayList which can grow as you need it. The method ArrayList.toArray( T[] a ) gives you back your array if you need it in this form.

List<String> where = new ArrayList<String>();
where.add( ContactsContract.Contacts.HAS_PHONE_NUMBER+"=1" );
where.add( ContactsContract.Contacts.IN_VISIBLE_GROUP+"=1" );

If you need to convert it to a simple array...

String[] simpleArray = new String[ where.size() ];
where.toArray( simpleArray );

But most things you do with an array you can do with this ArrayList, too:

// iterate over the array
for( String oneItem : where ) {
    ...
}

// get specific items
where.get( 1 );
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
tangens
  • 39,095
  • 19
  • 120
  • 139
  • 11
    What's the point in using Array if you can do the same with ArrayList? – Skoua Jan 11 '17 at 15:44
  • 7
    @Skoua Arrays are more efficient. Pre-defining the object size allows the compiler to optimize memory. For some applications, it matters. A small app running on a modern computer can probably get away with a lot of Lists before memory becomes a problem. – DraxDomax Dec 12 '19 at 12:33
  • Regarding the difference: it's a different question [Array or List in Java. Which is faster? - Stack Overflow](https://stackoverflow.com/questions/716597/array-or-list-in-java-which-is-faster) – user202729 Oct 06 '21 at 00:10
121

Use a List<String>, such as an ArrayList<String>. It's dynamically growable, unlike arrays (see: Effective Java 2nd Edition, Item 25: Prefer lists to arrays).

import java.util.*;
//....

List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
System.out.println(list); // prints "[1, 2, 3]"

If you insist on using arrays, you can use java.util.Arrays.copyOf to allocate a bigger array to accomodate the additional element. This is really not the best solution, though.

static <T> T[] append(T[] arr, T element) {
    final int N = arr.length;
    arr = Arrays.copyOf(arr, N + 1);
    arr[N] = element;
    return arr;
}

String[] arr = { "1", "2", "3" };
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3]"
arr = append(arr, "4");
System.out.println(Arrays.toString(arr)); // prints "[1, 2, 3, 4]"

This is O(N) per append. ArrayList, on the other hand, has O(1) amortized cost per operation.

See also

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • You can double the size of the array every time the capacity is not enough. That way append will be amortized O(1). Probably what `ArrayList` does internally. – Siyuan Ren Jan 24 '14 at 07:55
68

Apache Commons Lang has

T[] t = ArrayUtils.add( initialArray, newitem );

it returns a new array, but if you're really working with arrays for some reason, this may be the ideal way to do this.

xenoterracide
  • 16,274
  • 24
  • 118
  • 243
41

There is another option which i haven't seen here and which doesn't involve "complex" Objects or Collections.

String[] array1 = new String[]{"one", "two"};
String[] array2 = new String[]{"three"};

// declare a new array with enough space for all elements
String[] combinedArray = new String[array1.length + array2.length];

// copy the separate arrays into the combined array
System.arraycopy(array1, 0, combinedArray, 0, array1.length);
System.arraycopy(array2, 0, combinedArray, array1.length, array2.length);
aclima
  • 630
  • 1
  • 11
  • 20
  • 8
    this should be the accepted answer considering "don't use x, use y" is not an answer to "how to use x" but to "which alternatives are better than x?" – rado Apr 30 '21 at 20:54
  • I remember all those years back stumbling into this question, reading the existing answers and thinking to myself "Surely there's gotta be an easier way to handle this OOTB!?". This solution avoids importing entire utility modules from elsewhere, or using an entirely different data structure... just to update a pre-existing array. – aclima Jul 11 '23 at 18:30
15

There is no method append() on arrays. Instead as already suggested a List object can service the need for dynamically inserting elements eg.

List<String> where = new ArrayList<String>();
where.add(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1");
where.add(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1");

Or if you are really keen to use an array:

String[] where = new String[]{
    ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
    ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1"
};

but then this is a fixed size and no elements can be added.

Robert
  • 8,406
  • 9
  • 38
  • 57
11

I've made this code! It works like a charm!

public String[] AddToStringArray(String[] oldArray, String newString)
{
    String[] newArray = Arrays.copyOf(oldArray, oldArray.length+1);
    newArray[oldArray.length] = newString;
    return newArray;
}

I hope you like it!!

AngeL
  • 250
  • 4
  • 10
9

As tangens said, the size of an array is fixed. But you have to instantiate it first, else it will be only a null reference.

String[] where = new String[10];

This array can contain only 10 elements. So you can append a value only 10 times. In your code you're accessing a null reference. That's why it doesnt work. In order to have a dynamically growing collection, use the ArrayList.

Simon
  • 9,255
  • 4
  • 37
  • 54
9

There are many ways to add an element to an array. You can use a temp List to manage the element and then convert it back to Array or you can use the java.util.Arrays.copyOf and combine it with generics for better results.

This example will show you how:

public static <T> T[] append2Array(T[] elements, T element)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + 1);
    newArray[elements.length] = element;

    return newArray;
}

To use this method you just need to call it like this:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, "four");
System.out.println(Arrays.toString(numbers));

If you want to merge two array you can modify the previous method like this:

public static <T> T[] append2Array(T[] elements, T[] newElements)
{
    T[] newArray = Arrays.copyOf(elements, elements.length + newElements.length);
    System.arraycopy(newElements, 0, newArray, elements.length, newElements.length);

    return newArray;
}

Now you can call the method like this:

String[] numbers = new String[]{"one", "two", "three"};
String[] moreNumbers = new String[]{"four", "five", "six"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(numbers, moreNumbers);
System.out.println(Arrays.toString(numbers));

As I mentioned, you also may use List objects. However, it will require a little hack to cast it safe like this:

public static <T> T[] append2Array(Class<T[]> clazz, List<T> elements, T element)
{
    elements.add(element);
    return clazz.cast(elements.toArray());
}

Now you can call the method like this:

String[] numbers = new String[]{"one", "two", "three"};
System.out.println(Arrays.toString(numbers));
numbers = append2Array(String[].class, Arrays.asList(numbers), "four");
System.out.println(Arrays.toString(numbers));
Teocci
  • 7,189
  • 1
  • 50
  • 48
7
String[] source = new String[] { "a", "b", "c", "d" };
String[] destination = new String[source.length + 2];
destination[0] = "/bin/sh";
destination[1] = "-c";
System.arraycopy(source, 0, destination, 2, source.length);

for (String parts : destination) {
  System.out.println(parts);
}
dforce
  • 2,136
  • 3
  • 20
  • 36
6

Adding new items to String array.

String[] myArray = new String[] {"x", "y"};

// Convert array to list
List<String> listFromArray = Arrays.asList(myArray);

// Create new list, because, List to Array always returns a fixed-size list backed by the specified array.
List<String> tempList = new ArrayList<String>(listFromArray);
tempList.add("z");

//Convert list back to array
String[] tempArray = new String[tempList.size()];
myArray = tempList.toArray(tempArray);
Tom
  • 16,842
  • 17
  • 45
  • 54
Kris
  • 719
  • 1
  • 11
  • 19
  • 1
    Ah, I see, you used the `` tag and this had problems with the generic types. Please try to avoid this tag, since ... it has problems, and indent your code with 4 whitespaces to get the proper formatting. I did that for your question :). – Tom Dec 11 '15 at 17:09
5

You need to use a Collection List. You cannot re-dimension an array.

Paligulus
  • 493
  • 1
  • 4
  • 14
3

If you would like to store your data in simple array like this

String[] where = new String[10];

and you want to add some elements to it like numbers please us StringBuilder which is much more efficient than concatenating string.

StringBuilder phoneNumber = new StringBuilder();
phoneNumber.append("1");
phoneNumber.append("2");
where[0] = phoneNumber.toString();

This is much better method to build your string and store it into your 'where' array.

RMachnik
  • 3,598
  • 1
  • 34
  • 51
3

I'm not that experienced in Java but I have always been told that arrays are static structures that have a predefined size. You have to use an ArrayList or a Vector or any other dynamic structure.

npinti
  • 51,780
  • 5
  • 72
  • 96
3

If one really want to resize an array you could do something like this:

String[] arr = {"a", "b", "c"};
System.out.println(Arrays.toString(arr)); 
// Output is: [a, b, c]

arr = Arrays.copyOf(arr, 10); // new size will be 10 elements
arr[3] = "d";
arr[4] = "e";
arr[5] = "f";

System.out.println(Arrays.toString(arr));
// Output is: [a, b, c, d, e, f, null, null, null, null]
Baked Inhalf
  • 3,375
  • 1
  • 31
  • 45
2

you can create a arraylist, and use Collection.addAll() to convert the string array to your arraylist

ratzip
  • 113
  • 2
  • 11
2

Size of array cannot be modified. If you have to use an array, you can use:

System.arraycopy(src, srcpos, dest, destpos, length); 
frianH
  • 7,295
  • 6
  • 20
  • 45
Jiao
  • 53
  • 5
2

You can simply do this:

System.arraycopy(initialArray, 0, newArray, 0, initialArray.length);
0

It's also possible to pre-allocate large enough memory size. Here is a simple stack implementation: the program is supposed to output 3 and 5.

class Stk {
    static public final int STKSIZ = 256;
    public int[] info = new int[STKSIZ];
    public int sp = 0; // stack pointer
    public void push(int value) {
        info[sp++] = value;
    }
}
class App {
    public static void main(String[] args) {
        Stk stk = new Stk();
        stk.push(3);
        stk.push(5);
        System.out.println(stk.info[0]);
        System.out.println(stk.info[1]);
    }
}
baz
  • 1,317
  • 15
  • 10
0

It is not compiling because an array has no function named append the better and the correct way to go with is to use ArrayList

import java.util.ArrayList;

ArrayList where = new ArrayList<String>();

where.add(ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1")
where.add(ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1")
random_hooman
  • 1,660
  • 7
  • 23
-1

books[books.length + 1] = new_book_name;

array_name[array_name.length + 1] = "New Value";