JAVA - Duda List<Vector<Float>> y método clear()

Buenas a todos!

Os cuento, estoy leyendo datos de unos ficheros de texto y los estoy almacenando en una estructura bidimensional del tipo List<Vector<Float>>, básicamente seria una matriz de dos dimensiones de 2000 filas x 700 columnas.

el tema es que cuando leo de ficheros y voy construyendo la estructura tengo un problema, al hacer el return esta vacía. Lo que hago es, construyo las filas una a una y luego con el metodo add de List, voy añadiendo filas. Al final de cada construccion de fila hago un clear(), porque si no me lo mete todo en una fila enorme. Os pego el codigo que sera vera mas claro.

public static List<Vector<Float>> readFile(String file, String separator)
    throws FileNotFoundException, IOException {
      Vector <Float> row = new Vector <Float>();
      List <Vector <Float>> dataset = new ArrayList<Vector <Float>>();
      BufferedReader br = new BufferedReader (new FileReader (file));
      Float i;
      
      String line = br.readLine();
      while (line != null)
      {
          String token;
          StringTokenizer st = new StringTokenizer(line, separator);
          while (st.hasMoreTokens()) {
              token = st.nextToken();
              i = new Float(token);
              row.addElement(i);
          }
          dataset.add(row);
          row.clear();  //aqui limpio la fila
          line = br.readLine();
      }
      System.out.println(dataset);
      br.close();

      return dataset;
    }


Cuando ejecuto mi programa, observo que me ha hecho una lista de 2000 elementos pero cada uno de ellos esta vacio. Pero si hago un print de la fila antes de hacer el clear() veo que tiene los elementos.

Alguna idea?
Lo que metes a la lista no son copias de objetos sino los mismos objetos, es decir, si metes un vector en la lista y modificas después el vector original, estás modificando el vector de la lista puesto que es el mismo.

O metes en la lista una copia del vector (row.clone()) o creas el vector en la iteración que lee las líneas. Yo pondría el "Vector <Float> row = new Vector <Float>();" justo encima de la declaración "String token" y solucionado.
Si señor, gracias crack! Lo que no acabo de ver es que diferencia habia entre utilizar clear() (que entiendo que se carga los objectos) y meter el Vector <Float> row = new Vector <Float>(); en el bucle.
Al meter el vector en la iteración, recreas el vector cada vez y luego lo añades a la lista, aquí se están metiendo copias?

Como verás soy novatillo y muchos conceptos no los tengo claros.

Gracias de nuevo
Las variables no son más que enlaces a objetos. Tienes row enlazando a un objeto Vector<Float>, al meterlo en la lista lo que haces es crear otro enlace al mismo objeto al que enlaza row, es decir, tienes un objeto accesible mediante 2 enlaces (row y un elemento de la lista). Al hacer el row.clear(), estás haciendo el clear sobre el objeto enlazado por row, que es el mismo objeto que es parte de la lista. En tu caso estabas trabajando todo el tiempo con el mismo objeto por lo que terminabas la iteración con una lista de 2000 elementos y todos y cada uno de esos elementos eran un enlace al mismo objeto al que enlazaba row, objeto en el que habías usado el método clear().

No sé si "enlazar" es el término correcto para explicar esto, tal vez "apuntar" sería más concreto. En fin, creo que se entiende.

El método clear() elimina todos los objetos enlazados dentro del vector, pero el objeto sigue siendo el mismo. Sí, al crear el vector en el bucle lo que estás haciendo es crear un objeto nuevo en cada iteración, en vez de trabajar todo el tiempo con el mismo. Por eso la otra opción era meter en la lista una copia del objeto, es decir, row.clone().
Ok creo que me queda claro. Ahora la pregunta del millon, que es más optimo, trabajar con arraylist y Vector, o con una matriz pura y dura de tamaño fijo (Float[2000][700]).

Lo digo porque ahora tengo que empezar a realizar calculos sobre los elementos (medias, desviaciones, etc) e imagino que esto puedo ser clave.

Saludos
5 respuestas