Foro sobre Java SE > HashCode para calcular objetos diferentes
Buenas,
Que es "una propiedad poblacional"? Puedes poner un ejemplo de: "he creado una propiedad poblacional donde almaceno los diferentes hashCodes y en el método lo actualizo sumando los hashCode del nuevo objeto"? La verdad es que no se entiende...
Un saludo
Puestos a no entender: "... un método que cree objetos de un tipo con parámetros de forma aleatoria".
¿Qué parámetros?.
Igual quedaría todo más claro, si publicases el código que ya tienes hecho.
Me parece que te estas enredando mucho con los hashcodes.
Si lo que quieres es crear una lista de elementos aleatorios, por ejemplo enteros, y determinar si los diferentes son menos de la mitad, hay maneras simples de lograrlo, sin usar los hashcodes.
Apenas hay casos donde sea necesario usar directamente los hashcodes.
Perdón si no se entendía. Es que en mi facultad llaman "propiedad poblacional" a un atributo estático que sirve para contar el número de un objeto en concreto que se crean mediante un método, vamos, un contador.
Respecto a lo de generar un objeto de un tipo con sus parámetros aleatorios me refiero a a que los atributos de ese tipo se generen de forma aleatoria. En este caso, es el tipo App, cuyos atributos son nombre, tamaño, fechaVersion, numInstalaciones, precio y desarrollador.
Y lo de usar los hashCodes para el porcentaje de diferencia es porque es impuesto, yo no creo que lo hiciera así tampoco. De ahí mi duda para usarlos.
Aquí dejo el código:
package fp.tipos.apps;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Random;
public class FactoriaApps {
private static Integer codigos = 0;
private static Integer numCodigos = 0;
public static Integer getCodigos(){
return codigos;
}
public static App createApp(Random rnd){
String nombre = cadenaAleatoria(rnd, 5);
Double tamaño = rnd.nextDouble() * 1024.0;
Calendar fechaVersion = Calendar.getInstance();
fechaVersion.set(2000, 3, 3);
Integer numInstalaciones = rnd.nextInt(2000001);
Double precio = rnd.nextDouble() * 6.0;
String desarrollador = cadenaAleatoria(rnd, 3);
App a = new AppImpl(TipoSO.ANDROID, nombre, tamaño, fechaVersion, numInstalaciones, precio, desarrollador);
codigos = codigos + a.getSO().hashCode() + a.getDesarrollador().hashCode()*31 + a.getNombre().hashCode()*31;
if(codigos < numCodigos) //aquí es donde no sé que hacer para el porcentaje
return a;
}
Saludos
Esa propiedad numCodigos no se actualiza nunca, y tampoco veo cómo podría hacerse.
Por lo que veo, se trataría de determinar cuantos códigos son diferentes.
Para ello, puedes almacenar los códigos en una List. Para obtener cuantos son diferentes, puedes usar un Set sobre una copia de la lista de códigos, y comparar su tamaño con la List de códigos. De esa manera puedes saber si el % de diferentes es menor de la mitad.
Al margen de todo, esta manera de diseñar, usando propiedades estáticas... Comprendo que te obliguen a ello, pero mejor olvídalo cuanto antes :)
codigos = codigos + a.getSO().hashCode() + a.getDesarrollador().hashCode()*31 + a.getNombre().hashCode()*31;
Yo no entiendo esa linea. Porque acumulas los hashcode sumandolos a un integer? Y sobre todo: porque multiplicas los hashcode por 31?
Realmente te han dicho que tienes que hacer esto usando hashcode? No seria usando equals()?
Un saludo
Por si te sirve de ayuda:
public class NewMain {
public static void main(String[] args) {
List<Integer> listaCodigos = new ArrayList<>(Arrays.asList(24, 45, 5, 8, 5, 78, 1, 25, 6, 45));
listaCodigos.stream().forEach((Integer codigo) -> System.out.println(" codigo= " + codigo + ", frecuencia= " + Collections.frequency(listaCodigos, codigo)));
Set<Integer> noDuplicados = new HashSet<>(listaCodigos);
noDuplicados.stream().forEach((Integer codigo) -> System.out.print(codigo + " "));
}
}
Una manera de contar los códigos no duplicados:
public class NewMain {
public static void main(String[] args) {
List<Integer> listaCodigos = new ArrayList<>(Arrays.asList(24, 45, 5, 8, 5, 78, 1, 25, 6, 45));
System.out.println("numero total de códigos= " + listaCodigos.size()
);
System.out.println("número de codigos no duplicados= " + listaCodigos
.stream()
.filter((Integer codigo) -> Collections.frequency(listaCodigos, codigo) == 1)
.count());
}
}
Guenas.
No acabo de pillar lo que quieres lograr.
Doy por supuesto que lo que quieres hacer es saben en cuantos casos los parámetros iniciales han sido los mismos. Es decir, cada objeto distinto creado que cntiene la mismo información.
Olvidate del hashcode. En la mayor parte de casos te genera un hashcode distinto por cada objeto, aunque contengan los mismos datos.
Sobreescribe el metodo equals() y algun metodo que te devuelva una key identica si el cotenido es identico y usalo en un set o map. Luego haz los tratamientos que te indican.
Un saludo
Al hilo de la cuestión, hay una manera de crear clases cuyas instancias se puedan crear y comparar con seguridad.
import java.util.Objects;
public class Prueba {
public static Prueba create(String cadena, Integer numero) {
return new Prueba(cadena, numero);
}
private final String cadena;
private final Integer numero;
private Prueba(String cadena, Integer numero) {
this.cadena = cadena;
this.numero = numero;
}
@Override
public String toString() {
return "Prueba{" + "cadena=" + cadena + ", numero=" + numero + '}';
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + Objects.hashCode(this.cadena);
return 59 * hash + Objects.hashCode(this.numero);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Prueba other = (Prueba) obj;
if (!Objects.equals(this.cadena, other.cadena)) {
return false;
}
return Objects.equals(this.numero, other.numero);
}
public String getCadena() {
return cadena;
}
public Integer getNumero() {
return numero;
}
}
public class PruebaBuilder {
public static PruebaBuilder create() {
return new PruebaBuilder();
}
private String cadena;
private Integer numero;
private PruebaBuilder() {
}
public PruebaBuilder setCadena(String cadena) {
this.cadena = cadena;
return this;
}
public PruebaBuilder setNumero(Integer numero) {
this.numero = numero;
return this;
}
public Prueba createPrueba() {
return Prueba.create(cadena, numero);
}
}
Hola, estoy intentando hacer un método que cree objetos de un tipo con parámetros de forma aleatoria, pero a la vez que almacene los hashCode de los diferentes objetos creados y que si en algún momento el porcentaje de objetos diferentes es menor de un 50% se lance una excepción.
Esta última parte es en la que me he quedado atascado. He creado una propiedad poblacional donde almaceno los diferentes hashCodes y en el método lo actualizo sumando los hashCode del nuevo objeto. Pero no sé como hacer para que sean menor que el 50% de los objetos creados. A ver si alguien puede echarme una mano.
Saludos!