El objetivo es llenar un vector de Hashtables con Hashtables.

Para hacerlo, itero sobre un cursor, coloco lo que encuentra el cursor en una Hashtable y luego agrego la Hashtable al vector, así:

Vector<Hashtable<String, String>> v = new Vector<Hashtable<String, String>>();
Hashtable<String,String> h = new Hashtable<String,String>();

while(cursor.moveToNext()) {
    h.put("name", cursor.getString(0));
    h.put("region", cursor.getString(1));
    h.put("_id", cursor.getString(2));

    v.addElement(h);
}

El resultado es un Vector relleno con el último elemento del cursor, si el cursor itera sobre X elementos, entonces el Vector tiene X veces la última tabla hash creada.

Agregar esta línea resuelve el problema:

Vector<Hashtable<String, String>> v = new Vector<Hashtable<String, String>>();
Hashtable<String,String> h = new Hashtable<String,String>();

    while(cursor.moveToNext()) {
        h = new Hashtable<String,String>();   // <--THIS LINE HERE
        h.put("name", cursor.getString(0));
        h.put("region", cursor.getString(1));
        h.put("_id", cursor.getString(2));

        v.addElement(h);
    }

Pero no entiendo completamente por qué ...

¿El vector solo mantiene punteros a los Hashtables ...?

Gracias chicos.

0
FelDev 9 nov. 2017 a las 23:17

2 respuestas

La mejor respuesta

En su primer ejemplo de código, cada iteración a través del ciclo while rellena lo mismo Hashtable con el contenido de la posición actual del cursor. En su segundo ejemplo de código, llamar al constructor (la parte new Hashtable()) asegura que cada iteración rellene un Hashtable diferente cada vez.

Tenga en cuenta que con las colecciones, es posible modificarlas de formas que no son inmediatamente obvias. Imagina que tenemos este programa:

public static void main(String[] args) {
    Set<String> set = new HashSet<>();
    set.add("hello");
    set.add("world");

    Vector<Set<String>> v = new Vector<>();
    v.add(set);

    set.clear();

    System.out.println(v);
}

Le sorprenderá saber que esto imprime lo siguiente:

[[]]

Cuando add() el Set al Vector, no sucede nada para "bloquear" su contenido. Así que los cambios adicionales en Set también afectarán a Vector.

De manera similar, en su programa, después de la primera iteración del ciclo, su Vector tendrá una única referencia a un Hashtable con el contenido de la primera posición del cursor. Pero luego se ejecuta su segunda iteración, sobrescribe el contenido de Hashtable y add() vuelve a hacerlo. Ahora su Vector contendrá dos referencias (al mismo Hashtable), cada una con el contenido de la segunda posición del cursor.

Este patrón se repetirá hasta que termine su ciclo while, momento en el que su Vector tendrá X referencias (al mismo Hashtable), cada una con el contenido de la última posición del cursor.

1
Ben P. 9 nov. 2017 a las 20:45

En el primer bloque de código, simplemente está sobrescribiendo el mismo objeto, así que digamos que ha repetido el ciclo while dos veces. si la primera instancia h tiene name = "a", region = "b" y _id = "c", en la siguiente iteración, dado que no crea una nueva instancia, los campos name, region y _id del objeto serán anulados por cualquier valor que les asignes. Por lo tanto, tiene dos elementos y ambos tienen los mismos valores para sus atributos.

1
HaroldSer 13 nov. 2017 a las 03:48