Duda con conceptos de arreglos, objetos y punteros
Hola!
Tengo una duda, ya resolvi, el problema pero no me queda claro lo que hice o mejor creo que lo que hice es una burrada pero funciona pero no puedo quedarme con la duda por eso les pregunto a ustedes
He aqui mi problema ....
Tengo esta clase
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.io.IOException;
import java.lang.InterruptedException;
import java.util.logging.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
public class GetDataFromDB {
public rowCliente[] buscarCliente() throws IOException, NoSuchAlgorithmException, SQLException, InterruptedException
{
String sql;
Database db = new Database();
db.Conectar("5432", "union_seguros", "webservices", "webservices", "localhost", "org.postgresql.Driver","postgresql");
sql = "SELECT * FROM t_clientes";
ResultSet rs = db.exec_sel(sql);
final int max = db.CantRegistros(rs);
rowCliente vec[] = new rowCliente[max];
// Fetch each row from the result set
int cont=0;
rs.beforeFirst();
while (rs.next())
{
// Get the data from the row using the column index y pasandola al beam
int id = Integer.parseInt(rs.getString("f_id"));
vec[cont]=new rowCliente();
vec[cont].setId(id);
//t.setId(id);
vec[cont].setNombre(rs.getString(2));
vec[cont].setApellido(rs.getString(3));
vec[cont].setCedula(rs.getString(4));
vec[cont].setRnc(rs.getString(5));
//vec[cont] = t;
cont++;
//------
}
/*
for (int i=0;i<vec.length;i++)
{
System.out.println("for===>"+i+"*********");
vec[i].printcliente();
System.out.println("*********");
}
*/
rs.close();
return vec;
}
}
///Esta es la clase qe la instanciaba----
import setResultado.*;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
public class TestDB
{
public static void main(String[] args) throws IOException, SQLException,InterruptedException,NoSuchAlgorithmException
{
GetDataFromDB obj = new GetDataFromDB();
int longitud=obj.buscarCliente().length;
rowCliente []arr=obj.buscarCliente();
//arr[2].printcliente();System.out.println("------------------------");;
for(int i=0;i<longitud;i++)
arr[i].printcliente();
}
Ahora el problema, cuando imprimia el vector en la segunda clase siempre me salia el ultimo, es decir, al parecer cada una de las posiciones del vector tenian la ultima record.
Al hacier rowCliente vec[] = new rowCliente[max];
pense que el creaba un vector de max posiciones del tipo rowCliente pero al parecer no es asi. Por que al asignar vec[cont] = t; solo lo hacia en ese momento al final todo quedaba en el ultimo solo haciedno
vec[cont]=new rowCliente();
y he ahi mi duda porque hacer esto de nuevo no se supone que al declarar el vector con las max posiciones era esto lo que hacia?
No entiendo mucho el concepto al parecer todo esto se mueve internamente con direcciones de memoria y como yo esyoy muy acostumbrado a C para mi el manejo de memoria tene que ser explicito, punteros y +punteros, pero eso aqui no existe.
Alguien puede darme luz sobre esta duda?
Solo es como referencia general
- Inicie sesión o regístrese para enviar comentarios
C
si vienes de C, te puede facilitar imaginarte un * al final de cada declaración de objeto. y piensa que el new es como un malloc, con una inicialización de valores de la estructura que estás alojando en esa memoria.
En Java puedes declarar tus arreglos como
rowCliente vec[]
o comorowCliente[] vec
pero creo que es más común en Java usar la segunda variante. También es más común poner la llave que abre al final de la misma línea, y poner la llave que cierra a la misma altura del bloque que está cerrando, así:if (x) {
} else {
}
}
No encontré que tuvieras una variable
t
. Supongo que quitaste la declaración y tenías algo comorowCliente t = new rowCliente(); t.setId(bla); t.bla(ble);
etc y al final nada más hacíasvec[cont] = t
como mencionas al final. Pues eso debe funcionar bien:// Get the data from the row using the column index y pasandola al beam
int id = Integer.parseInt(rs.getString("f_id"));
rowCliente t = new rowCliente();
t.setId(id);
t.setNombre(rs.getString(2));
t.setApellido(rs.getString(3));
t.setCedula(rs.getString(4));
t.setRnc(rs.getString(5));
vec[cont++] = t;
}
Al final de eso cada elemento de
vec
debe tener una instancia derowCliente
distinta. Que por cierto te recomiendo seguir la convención de nombrar tus clases con mayúscula, es decir RowCliente.Pues mira , que tu y yo
Pues mira , que tu y yo creiamos lo mismo pero la verdad no era asi. Yo suponia al igual que tu que cada vez que yo asignaba nuevos valores a t y luego lo pasaba al vector pues eran diferentes pero no era asi. Si mandaba a imprimir lo que tenia el vector en ese mismo momento si era lo que asignaba de t pero al terminar el ciclo inmediatamente al hacer esto
{
System.out.println("for===>"+i+"*********");
vec[i].printcliente();
System.out.println("*********");
}
Todas las instancias del vector solo me daban el ultimo record. Esa era mi gran pregunta , por que ?
Suponia que era al asignar el valor de t a una posicioni del vector estos "valores" debian salvarse en otro espacio de memoria pero parece que no es asi. Como dijiste si borre la declaracion de t y estaba, obviamente, como tu dices, claro esa declaracion estaba fuera del ciclo.
En resumen, lo que tu me dices que debio de funcionar y que es lo mismo que yo pienso, no funcionaba solo tomaba el ultimo record para todo.
código completo
Habría que ver tu código completo. Seguramente había algún error, probablemente sólo hacías el
new
una vez y entonces guardas la misma instancia en todas las posiciones del arreglo, y queda con los valores de la última iteración.Puedes verificar si tienes distintas instancias en el arreglo o si tienes realmente la misma en todas las posiciones, simplemente vec[0] == vec[1] a ver qué te dice...
Si son las mismas. Lo que no
Si son las mismas. Lo que no se es tengo que hacer
t = new rowCliente(); </code? antes de asignar cada valor de T al vector. Tienes razon en que solo instancie una vez el valor de t pero suponia que cada vez que asignaba valores nuevos estos se copiaban a la instancia del venctor pero al parecer lo que copia solo es la direccion de memoria.
en C
Tienes que crear un nuevo objeto en cada iteración. Si no, es como si en C hicieras esto (probablemente tengo algo mal porque estoy algo oxidado ya):
rowCliente *t = new malloc(sizeof(rowCliente));
rowCliente vec[5];
int cont =0;
while (condicion) {
vec[cont++] = t;
t->algo="X";
}
eso tendría el mismo efecto: todos los elementos del arreglo hacen referencia al mismo rowCliente.
Efectivamente, tienes que
Efectivamente, tienes que crear un nuevo objeto en cada iteración ya que si solo le asignas el valor, siempre tendra el mismo debido a que en java solo se manejan como apuntadores al espacio de memoria donde esta el valor es decir apuntan al objeto, entonces cuando creas el objeto y le haces un "=" ese objeto apunta a la direccion de memoria donde vivie ese objeto, cuando metes el objeto al arreglo, solo metes ese apuntador, pero se queda apuntando al mismo objeto, cuando llega tu ultimo registro, el objeto se queda con ese ultimo registro y tu arreglo se queda lleno con apuntadores hacia el mismo objeto es por eso que cuando lo recorres te muestra lo mismo, la solución es crear nuevos objetos en cada iteración y meterlos al arreglo, como quiera no afecta el performance de tu aplicación ya que de eso se encarga el garbage collectos..
Salu2.
realiza esta prueba haber que
realiza esta prueba haber que te sale...
String holaMundo = new String("Hola Mundo");
se crea un objeto en memoria que contiene la cadena "Hola mundo", y ese objeto es apuntado por la variable holaMundo...
despues haces lo siguiente:
String segundaCadena = holaMundo;
cual creen que sea el resultado de estas comparaciones?
holaMundo==segundaCadena y holaMundo.equals(segundaCadena)
respondan y despues lo prueban...
algo similar sucedio en tu caso Macaruchi.
Uffff ... me imagine eso al
Uffff ... me imagine eso al final. Pero para un tipo como yo que viene de C entender esto de forma implicita es raro. Es decir, en C si trabajaba con memoria manejaba mis punteros y ya. Aqui es raro porque como supuestamente no maneja punteros pense que era solo copiando los datos que estaba.
Ya entendi bien. Gracias por explicarme este concepto.
tiene que ver mas con la
tiene que ver mas con la creación de objetos,que con punteros pero es similar y mucho mas facil de manejar.
Se puede hacer esto con arrays????
Quiero pasarle un array a otra clase pero no se si asi es la forma mas propia de hacerlo??
LlenaList m = new LlenaList (lAttach);
//Clase B
public Arraylist lAttach=new ArrayList();
public LlenaList (final ArrayList lAttach){ // Constructor...
this.lAttach=lAttach;
}
@west140 Crea una pregunta
@west140
Crea una pregunta nueva para esto, no tiene relación con la pregunta original.
Sobre lo que preguntas te diré que "casi". Siendo estrictos ArrayList no es un array, pero te contesto en la otra pregunta que crees.
En verdad..
Siempre las habia llenado con objetos, pero se la habia pasado asi, pensando de otra forma un array es un objeto entonces no habria problema con llenarla asi. Pero dime q piensas??