style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

ayuda con inicios de ArrayList y objetos

Tengo problemas con el manejo de ArrayList que contienen objetos,
la idea es la siguiente:
tener un objeto color que contiene un id de base de datos, nombre y valores rgb.
conforme recorro el resultset de la consulta llenar un ArrayList con los objetos que tienen esos valores.
luego regorrer el ArrayList , tomar el objeto y su metodo getNombre, si cumple una condicion activar su metodo pintarPanel().

Les pongo los fragmentos de codigo...

 
static ArrayList colores= new ArrayList();

static class vehiculo_colores {
        static String idvehiculo_colores;
        static String nombre;
        static int r,g,b;
       
        public vehiculo_colores(){
            idvehiculo_colores="";
            nombre="";
            r=0;
            g=0;
            b=0;
        }
        public vehiculo_colores(String id, String nom, int rr, int gg, int bb) {
            idvehiculo_colores=id;
            nombre=nom;
            r=rr;
            g=gg;
            b=bb;
        }
        public static void setDatos(String id, String nom, int rr, int gg, int bb) {
            idvehiculo_colores=id;
            nombre=nom;
            r=rr;
            g=gg;
            b=bb;
        }
        public void pintarPanel(){
            pColor.setBackground(new Color(r,g,b));
        }
        public String getId(){
            return idvehiculo_colores;
        }
        public String getNombre(){
            return nombre;
        }
        public Color getColorRGB(){
            Color c= new Color(r,g,b);
            return c;
        }
        public void imprime(){
            System.out.println(idvehiculo_colores+" "+
            nombre+" "+
            r+" "+
            g+" "+
            b);
        }
    }

//////////////////////////////

 
public static void llenaComboColores(){
        cbColor.removeAll();
        vehiculo_colores c = new vehiculo_colores();
        try{
            Conexion myDb = new Conexion();
            ResultSet rsp = null;
            rsp = myDb.consulta("Select * From vehiculo_colores Where tipo = 'ACTIVO' Order By color");
            while( rsp.next() ){      
                cbColor.addItem(rsp.getString("color")); //agregar el color al combobox
                c.setDatos(rsp.getString("idvehiculo_colores"),
                                        rsp.getString("color"),
                                        rsp.getInt("r"),
                                        rsp.getInt("g"),
                                        rsp.getInt("b"));
                colores.add(c);
            }
            rsp.close();
            myDb.cerrar();
             muestraColores();
        }
        catch( java.sql.SQLException e1){}
    }

//////////////////////////////

 
static public  void muestraColores(){
    System.out.println("colores size: "+colores.size());
    vehiculo_colores c= new vehiculo_colores();
   
    for(int n=0;n<colores.size();n++){
        System.out.print(n+"- ");
       
        c=(vehiculo_colores)colores.get(n);
        c.imprime();
    }
}

/////////
y el Output sale...

colores size: 353
0- 0 0 0
1- 0 0 0
2- 0 0 0
3- 0 0 0
4- 0 0 0
5- 0 0 0
6- 0 0 0
7- 0 0 0
.
.

Tambien intente lo intento asi....

 
static ArrayList<vehiculo_colores> colores= new ArrayList<vehiculo_colores>();

.
.
.

 
static public  void muestraColores(){
    System.out.println("colores size: "+colores.size());
    for(int n=0;n<colores.size();n++){
        System.out.print(n+"- ");
        colores.get(n).imprime();
     }
}

////////////////////
y el Output sale:

colores size: 353
0- 458 WHEAT B 238 216 174
1- 458 WHEAT B 238 216 174
2- 458 WHEAT B 238 216 174
3- 458 WHEAT B 238 216 174
4- 458 WHEAT B 238 216 174
.
.

Pareciera que no estoy reccoriendo el ArrayList o que se esta guardado el mismo objeto en todo el ArrayList
Quien pudiera orientarme

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de beto.bateria

Guardas el mismo

Guardas el mismo objeto:

public static void llenaComboColores(){
        cbColor.removeAll();
        vehiculo_colores c = new vehiculo_colores();
        try{
            Conexion myDb = new Conexion();
            ResultSet rsp = null;
            rsp = myDb.consulta("Select * From vehiculo_colores Where tipo = 'ACTIVO' Order By color");
            while( rsp.next() ){      
                cbColor.addItem(rsp.getString("color")); //agregar el color al combobox
                c.setDatos(rsp.getString("idvehiculo_colores"),
                                        rsp.getString("color"),
                                        rsp.getInt("r"),
                                        rsp.getInt("g"),
                                        rsp.getInt("b"));
                colores.add(c);
            }
            rsp.close();
            myDb.cerrar();
             muestraColores();
        }
        catch( java.sql.SQLException e1){}
    }

Recuerda que los objetos se manejan por direccion, en el while tienes el mismo objeto que le agregas a colores, solo le cambias los valores, entonces, los valores que imprimes son los del ultimo registro del resultset, lo que tendrias que hacer es crear un nuevo objeto (c = new vehiculo_colores();) antes de asignar valores.

+1 por hacer una pregunta que

+1 por hacer una pregunta que puede ser contestada ( es decir que explicar que es lo que pasa y tiene código )

En Java la palabra reservada static es muy diferente a como se usa en C, en C le asigna en espacio de memoria donde puede ser alcanzada siempre con la misma dirección ( hence static ) y en Java significa "attributo o método" de clase. Es decir que todos los elementos de la misma clase tienen el mismo valor.

Es por eso que los valores de r,g,b te salen siempre igual.

En el primer ejemplo, cuando iteras:

  1. static public  void muestraColores(){
  2.     System.out.println("colores size: "+colores.size());
  3.     vehiculo_colores c= new vehiculo_colores();
  4.    
  5.     for(int n=0;n<colores.size();n++){
  6.         System.out.print(n+"- ");
  7.        
  8.         c=(vehiculo_colores)colores.get(n);
  9.         c.imprime();
  10.     }
  11. }

En la linea 3 inicializas todos los valores a 0 por que estás ejecutando esto:

 public vehiculo_colores(){
            idvehiculo_colores="";
            nombre="";
            r=0;
            g=0;
            b=0;
        }

Aunque SI estás llamando al constructor de la clase y SI estas creando un nuevo objeto, las variables r,g,b son variables ( o atributos ) de clase, por lo que TODAS las instancias de esa clase tendrán siempre el mismo valor.

Es por eso que al iterarlos, te aprece lo mismo: "", 0, 0, 0

El ejemplo más claro es en tu segunda forma de iteración:

static public  void muestraColores(){
    System.out.println("colores size: "+colores.size());
    for(int n=0;n<colores.size();n++){
        System.out.print(n+"- ");
        colores.get(n).imprime();
     }
}

Ahí no estas inicializando de nuevo los valores, por lo que todos los elementos de tu lista tienen el valor del último elemento:

458 WHEAT B 238 216 174

Entonces, la solución es más o menos simple. Quita la palabra reservada static de todos los lugares donde aparezca. Quizá te salgan otros problemas como que Xyz cannot be invoked from an static context y así, en esos casos hay que crear una instancia para poder llamar a algún método.

Por cierto, en Java, los identificadores ( atributos, métodos, variables, nombre de clase etc. ) se escriben con camelCase ( sin guines bajos ) , los metodos y atributos empiezan con minúsculas y las clases con mayúsculas. Esto es por convención. Solamente en las constantes, se pone todo en mayúsculas , por ejemplo: public static int SIZE_OF_WORD = 1024; por lo que tu clase debería de haberse definido:

class VehiculoColores {
        String idvehiculoColores;
        String nombre;
        int r,g,b;
        ...
}

También es muy recomendable hacer los atributos privados:

class VehiculoColores {
        private String idvehiculoColores;
        private String nombre;
        private int r,g,b;
        ...
}

Espero que esto te sirva.

Imagen de bferro

El "static" en C y en Java son "similares"

C++ hereda de C la palabra reservada static y Java lo hereda de C++. Realmente no hay "mucha" diferencia en el uso de static en C y en Java, salvando por supuesto las diferencias en su modelo de programación.
Cuando se programa en C, resulta INCONVENIENTE en ocasiones la característica de las variables automáticas de desaparecer una vez que salen del ámbito (scope) del bloque en que fueron definidas.
Para resolver ese problema, el lenguaje C inventa las variables estáticas con el objetivo de lograr el control de su ámbito y a la vez conservar el valor de las mismas una vez que "salen" del bloque donde fueron definidas.
Se puede en C aplicar static a variables locales y a variables globales, pero también se puede aplicar a funciones.
Cuando se aplica a variables globales y a funciones se persigue el objetivo de que el enlace (linking) sea interno, de suerte que sean conocidas exclusivamente dentro de la unidad de compilación que las define y no se "van" a la tabla de símbolos a participar en un linking externo.

Cuando se aplica a variables locales se hace con el objetivo de que su ámbito sea el del bloque que las define pero su vida sea "global" durante toda la duración del programa.
El uso de static en Java persigue propósitos similares, controlando el ámbito de esas variables y funciones dentro de la clase (módulo) que las define, y permitiendo que su tiempo de vida sea global una vez que se carga la clase que las define.

Otra diferencia es que al ser

Otra diferencia es que al ser Java un lenguaje de programación orientado a objetos, los métodos y atributos de clase también se heredan y se pueden sobrrescribir ( lo cual no sirve de mucho en realidad porque de todas formas tienen que ser invocados usando la clase ). Existe la creencia de que esto no es posible en Java por la forma en la que el el compilador resuelve las referencias a los métodos.

Por ejemplo, si se define un método de clase llamado main:

class Padre {
  public static void main( String ... args ) {
    System.out.println("Iniciando programa");
  }
}

Y luego se crea una clase que herede de esta:

class Hijo extends Padre {}

Esta clase hereda y puede sobreescribir el método "main".

Si se invoca al inteprete de Java:

java Hijo

La salida es la que se espera, el comportamiento de la clase padre:

Iniciando programa

Si se cambia el comportamiento:

clas Hijo extends Padre  {
  public static void main( String ... args ) {
    System.out.println("Ya no");
  }
}

Se obtiene la nueva versión:

java Hijo
Ya no

El punto de confusión es que Java ( el compilador ) define de forma estática que método debe de ser llamado dependiendo del tipo de dato, por lo que si escribimos algo como esto:

class Demo {
  public static void main( String ... args ) throws Exception {
    Padre hijo = new Hijo();
    hijo.main();
   }
}

El compilador de forma estática ( sin recurrir a la información que hay en tiempo de ejecución ) determina que el método que va a llamar es el de Padre.main esto tiene una razón que por poco común he olvidado, pero cuando encuentre una referencia la pongo acá.

Sin embargo no significa que la clase hijo no heredó ese comportamiento, para demostrarlo se puede invocar el método main, resolviendolo de forma dinámica ( me refiero a tiempo de ejecución ) justo como los métodos de instancia.

A falta de un mejor mecanismo se puede simular esta invocación usando reflection:

class Demo {
  public static void main( String ... args ) throws Exception {
    Padre hijo = new Hijo();
    hijo.main(); // Llama al main del padre  

    hijo.getClass()
      .getMethod("main",String[].class )
      .invoke( null, ( Object)  new String[]{} ); // llama al main del hijo
  }
}

Colofón Es posible en Java ( más bien en algún lenguaje para la JVM ) hacer la resolución dinámica de los métodos de clase, sin tener que recurrir al reflection, yo lo hice en una versión de Ryz pero ya no lo integré al código principal porque hay todavía muchas otras cosas en el backlog que resolver ( como por ejemplo la declaración correcta de variables locales :P ) ¿Agregaría algún valor esta funcionalidad? La verdad es que no se me ocurren escenarios donde pudiera ser útil y por lo tanto pasó al whishlist de no se whichlist del wishlist original. jejeje

Imagen de ezamudio

soy necio

Los métodos estáticos de Java me parecen una porquería en la manera en que los implementaron, comparados con los métodos de clase en Objective-C. No se puede hacer referencia a la superclase más que por nombre, por lo tanto no hay realmente herencia en los métodos estáticos. Sí se pueden sobreescribir pero no sirve de nada. No sé qué les costaba, no veo por qué no podían hacer eso en Java, sé que el argumento es que el tipado dinámico vs estático pero realmente no entiendo por qué no podía usarse super y this en métodos estáticos para hacer referencia a la superclase y a la propia clase.

@implementation Padre

+ (NSString *)algo {
        return [[self class] className];
}
@end

@implementation Hijo

+ (NSString *)algo {
        return [NSString stringWithFormat:@"Hijo, super: %@", [super algo]];
}

@end

@implementation Nieto

+ (NSString *)algo {
        return [NSString stringWithFormat:@"estoy en el nieto, super %@", [super algo]];
}

@end

Teniendo esa estructura de clases, si mandamos a imprimir [Padre algo], [Hijo algo] y [Nieto algo], obtenemos:

Padre: Padre
Hijo: Hijo, super: Hijo
Nieto: estoy en el nieto, super Hijo, super: Nieto

En Java ni siquiera puedo hacer código similar.

Imagen de bferro

Lo que se hereda es el comportamiento de los objetos

Creo que ya hubo una discusión al respecto.
Lo que se hereda es el comportamiento de los objetos, que por supuesto están definidos por su clase en sus métodos de instancia. Eso quiere decir que no existe el polimorfismo asociado a los métodos estáticos, porque los métodos estáticos no implementan el comportamiento de los objetos. Que podamos referirnos a los métodos estáticos mediante referencias a objetos de su clase, es simple azúcar sintáctica para evitar escribir lo que realmente sucede que es Clase.metodo().
Cuando escribimos en una clase derivada, un método estático con la misma firma (signature) que un método estático en su clase Base, lo que estamos haciendo es ocultando ese método y usando el de la clase derivada, pero seguimos teniendo acceso a los dos mediante Base.metodo(); Derivada.metodo().

Java requiere de los métodos estáticos para poder escribir funciones globales, ajenas al comportamiento de los objetos. Que al escribir esas funciones dentro de una clase, ellas tengan acceso a la implementación de esas clases es otro boleto. Un ejemplo canónico es la clase java.lang.Math. Conceptualmente eso no es una clase: es un módulo que encapsula un conjunto de funciones matemáticas y así se hace saber en su diseño. Es una clase final, con constructor privado, sin método de fábrica y con todos sus métodos estáticos.
Esa es la carga que lleva Java sobre sus hombros por no incluir algún otro constructo para escribir funciones globales. Pero no es un pecado; es una forma de ver el problema.

En realidad si se puede...

En realidad si se puede... pero claro con truquitos por aquí y por allá :)

El código es Java 100% sin reflection ni nada pero no es algo que el lenguaje soporte de forma nativa ( es decir no hay una palabra reservada para ello ni nada ) pero de que se puede se puede :)

Imagen de ezamudio

leet? pffff

PFFF... "de que se puede se puede"... pero es algo que un simple mortal no puede hacer, es un secreto que sólo los L337 h4x0r sabemos y no lo vamos a compartir.

ObjC lo tiene como parte del lenguaje para que cualquier fulano lo pueda usar. Si en Java sólo los L337 h4x0r lo pueden hacer, es que no se puede usar: no te lo aceptan en ambientes enterprise ni se considera buena práctica usarlo porque no es algo estándar en el lenguaje.

Si de nuevo

Si, ya lo habíamos hablado pero otra veez, es divertido

Un ejemplo canónico es la clase java.lang.Math. Conceptualmente eso no es una clase: es un módulo que encapsula un conjunto de funciones matemáticas y así se hace saber en su diseño

Pues sí, pero como Java es un lenguaje de programación orientado a objetos y no tiene funciones lo tiene que hacer así; en una clase, con puros métodos de clase y con puros atributos de clase. Es una clase única y diferente en ese sentido, eso sí :)

Lo mismo pasa con otros paradigmas de programación. Han visto el intento de hacer OO en C? Se ve igual, se comporta igual, pero no dejan de ser estructuras porque al ser un lenguaje procedural, pues ... no tiene objetos ni clases. Lo mismo en los lenguajes de programación funcionales, lo que tienen para construir son .. pues funciones, aunque haya forma de hacerlas parecer estructuras o aunque haya forma de hacerlos parecer objetos siguen siendo funciones.

No podríamos decir que ya no lo son porque no se comportan como tales ( estructuras, funciones u objetos) . Lo siguen siendo, pero en el ámbito donde están definidas tienen un nombre u otro ( por eso se le llama paradigma ). En todo caso lo son ( estructuras, funciones u objetos ) anormales o inadaptados o disfuncionales, pero siguen siendo lo que son ( estructuras, funcionas u objetos ).

Por ejemplo en ningún lado de la documentación de Java se le llama a los métodos con el modificador static como métodos estáticos. Siempre se les dice métodos de clase, al menos repito en la documentación que hizo originalmente Sun y que ahora mantiene Oracle.

Pero si, es correcto, al final TODO es azúcar sintáctico y en realidad nada existe. El código Java es azúcar de bytecode, que a su vez es azúcar de C++ que a su vez es azúcar de C que es azúcar de ensamblador que es azúcar de código de máquina que es azúcar de ... ¿?

@ezamudio psssss pos claaaaaro, sino ¿¿¿pus luego???? ;)

Ahi va la L337 Scr33nsh0t:

Naahh en realidad no es porque sea así de elite ni nada, es porque como todos los trucos cuando sabes como funciona dices: Ahhh pues si esta rete-fácil. Como la del mago del wings que te saca una monedota de la oreja.

Estuve durante un buen rato considerándolo meter en Ryz pero como no le vi mayor utilidad y sí mucha dificultad, quedo relegado.

Por cierto, esto es por cierto algo que también usa Scala ( no exactamente en el mismo contexto porque Scala no tiene atributos ni métodos de clase ) pero pues por ahí va.

Override?

Pasa algo bien chistoso con el main... si haces herencia de otra clase con main entonces se ejecuta el main de la superclase pero si invocas un método estático en ambas clases pues se toma el de la clase donde llamas al metodo. Por ejemplo:

public class Statics extends Cosa {
    public static void main(String[] args) {
        a();
    }
   
   
    public static void a(){
        System.out.println("AAAA");
    }
}

class Cosa{
   
   
//    public static void main(String[] args) {
//        a();
//    }
   
   
    public static void a() {
        System.out.println("BBBBB");
    }
}

Imagen de bferro

No es nada "chistoso". No hay override de métodos estáticos

Así debe ser el comportamiento en el ejemplo que pones java.daba.doo.
No hay override de métodos estáticos y por esa razón no tienen comportamiento polimórfico. Como comenté en el post anterior: lo que se hereda es el comportamiento de los objetos y entonces es posible que se comporten de acuerdo con el polimorfismo basado en la herencia.

Al hacer override de los métodos de instancia se utiliza el mecanismo de despacho virtual para separar el contrato de la implementación. El contrato es conocido en tiempo de compilación atendiendo a la firma de los métodos de instancia y la implementación no es conocida hasta la ejecución cuando un tipo concreto de objeto ofrece (definida en su clase) una implementación concreta.

Cuando usas funciones estáticas (ojala y Java le hubiera llamado funciones y no métodos), los llamas de forma explícita especificando el tipo en el cual se definen los métodos (o usando azúcar sintáctica como si estuvieras llamando a un método de instancia).
Al usar los métodos estáticos llamas directamente a su implementación que no está atada a ningún contrato.

Cuando digo que Java debió haberles llamado funciones estáticas, me refiero a que en la literatura el término método se usa para referirse al "código" que un objeto usa para responder a un mensaje (a su invocación) y los métodos estáticos no están asociados al comportamiento de los objetos. Es por esa razón que a nivel de código decimos que no reciben el apuntador this.

Imagen de exception.h

Pues ahora si que mas que resuleto el problemita...

Me resulto en catedra XD
Gracias, el problema fue resuelto y ya manejo arrayslist de objetos.
Ahora me surgio otra duda, pero la pondre en otro punto. Mil gracias pos sus aportes ^^

private void cargaLineas(){
            try{
                ResultSet rsp;
                Conexion myDb = new Conexion();
                rsp=myDb.consulta("SELECT * FROM vehiculo_color_linea WHERE idvehiculo_lineas = '"+idvehiculo+"'");
                while(rsp.next()){
                    colorlineas.add(new VehiculosColoresLinea(rsp.getString("idvehiculo_color_linea")));
                }
                myDb.cerrar();
            }catch(SQLException ex){
                System.out.println(ex.getMessage()+ " " +ex.getLocalizedMessage());
            }
        }

Otra cosa que no mencionamos

Otra cosa que no mencionamos es que es altamente recomendado declarar tu tipo de datos como la interfaz y no como la implementación.

Es decir:

//Nap
ArrayList a = new ArrayList();
//yeap
List a = new ArrayList();

Create el buen hábito de hacerlo así.

Imagen de ezamudio

NOOOOOO

No concatenes SQL, usa queries parametrizados. Neto que tenemos que hacer más popular a Bobby Tables.

Tipico

@exception.h Si ponlo en otro

@exception.h Si ponlo en otro post

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">