How to create an infinite array?

5

I have a problem and I need to create an infinite, or rather undefined, array, so that I can enter as many data as I need ...

How could I do it? I'm using JDK6.

    
asked by anonymous 04.04.2014 / 11:51

2 answers

15

In Java arrays are fixed in size, specified in creation. If you need to store more elements that fit into the array, your only output is to create a new array, larger, and copy the elements already existing to it (plus the new one you're adding).

Fortunately, there's a ready class that does it for you: java.util.ArrayList . You use it as a list, usually, and the library takes care of the inside details for you:

ArrayList<String> lista = new ArrayList<String>();
lista.add("foo");
lista.add("bar");
lista.add("baz"); // Quantos elementos quiser, desde que caiba na memória
for ( String s : lista )
    System.out.println(s);

If you pass an integer parameter to the constructor, you specify the "initial capacity" of the list (i.e. the initial size of the inner array - so that you can store X elements before the list resizes for the first time). This can improve performance if you have an idea of how many elements the system will usually have to endure (in the middle case - no problem if in the worst case it needs more).

For an alternative based on linked lists instead of arrays (with the corresponding advantages and disadvantages), see java.util.LinkedList .

Note on data types

If your data is complex objects (including strings), this is the most straightforward solution. In the case of primitive types, on the other hand, the use of lists would bring autoboxing overhead:

ArrayList<Integer> lista = new ArrayList<Integer>();
lista.add(10);        // autobox
int x = lista.get(0); // autounbox

In this case, each element in the list will occupy additional memory ( 24 bytes per element on a 32-bit platform if I'm not mistaken). If this is a problem for you, all you have to do is simply use simple arrays and resize them manually.

class ListaInts {
    private int[] lista = new int[8];
    private int length = 0;

    public void add(int i) {
        if ( length == lista.length ) {
            // Copia toda a lista para um novo array, maior
            int[] novaLista = new int[lista.length * 2];
            System.arraycopy(lista, 0, novaLista, 0, length);
            // Substitui a lista original
            lista = novaLista;
        }
        lista[length++] = i;
    }
}
    
04.04.2014 / 12:27
4

The vectors always have to have a defined size, you can not create them with an indeterminate size.

To solve your problem, you can do this by hand, by creating new vectors each time it reaches its size limit, or you can use a class that Java has already created to help us with this task: java.lang.ArrayList as already said by @mgibsonbr.

Just to add to his response, I'm going to show source code snippet of class ArrayList that explains how this works (but no one needs to know to use it):

ArrayList.java

//o atributo elementData é do tipo Object, ou seja, guarda qualquer tipo de 
//variável com que não seja um primitivo
private transient Object[] elementData;

//você pode inicializar seu ArrayList indicando o tamanho do seu vetor, mas isso 
//costuma ser irrelevante para nós
public ArrayList(int initialCapacity) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    this.elementData = new Object[initialCapacity];
}

public ArrayList() {
    this(10); //por padrão, o ArrayList é criado com um vetor de tamanho de 10 elementos 
}

//esta é a parte que a lista aumenta seu tamanho, criando um novo vetor
//que garante que é possível armazenar todos os elementos da coleção
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

The ArrayList class is relatively large, has more than 1000 rows, I will not post all here, but if you are interested in viewing it, it is available for anyone to view your code as well as any JDK class.

Just so my answer is not incomplete, here's an example of use:

List<Integer> lista = new ArrayList<Integer>();
lista.add(1); //autoboxing, transforma automaticamente de int para Integer
lista.add(5);
System.out.println("Último elemento da lista: " + lista.get(lista.size()-1));

Prints:

  

Last list item: 5

    
04.04.2014 / 13:12