Tengo una ArrayList
con varios registros y una columna contiene nombres de gas como CO2 CH4 SO2, etc. Ahora quiero recuperar diferentes nombres de gas (únicos) solo sin la repetición de ArrayList
. ¿Cómo puede hacerse esto?
Tengo una ArrayList
con varios registros y una columna contiene nombres de gas como CO2 CH4 SO2, etc. Ahora quiero recuperar diferentes nombres de gas (únicos) solo sin la repetición de ArrayList
. ¿Cómo puede hacerse esto?
Respuestas:
Debería utilizar un Set
. A Set
es una colección que no contiene duplicados.
Si tiene un List
que contiene duplicados, puede obtener entradas únicas como esta:
List<String> gasList = // create list with duplicates...
Set<String> uniqueGas = new HashSet<String>(gasList);
System.out.println("Unique gas count: " + uniqueGas.size());
NOTA : Este HashSet
constructor identifica duplicados invocando los métodos equals () de los elementos .
java: no suitable constructor found for HashSet
. ¿Alguna idea de por qué ocurre esto?
El método distinto es una operación intermedia que filtra la secuencia y permite que solo valores distintos (de forma predeterminada, utilizando el método Object :: equals) pasen a la siguiente operación.
Escribí un ejemplo a continuación para su caso,
// Create the list with duplicates.
List<String> listAll = Arrays.asList("CO2", "CH4", "SO2", "CO2", "CH4", "SO2", "CO2", "CH4", "SO2");
// Create a list with the distinct elements using stream.
List<String> listDistinct = listAll.stream().distinct().collect(Collectors.toList());
// Display them to terminal using stream::collect with a build in Collector.
String collectAll = listAll.stream().collect(Collectors.joining(", "));
System.out.println(collectAll); //=> CO2, CH4, SO2, CO2, CH4 etc..
String collectDistinct = listDistinct.stream().collect(Collectors.joining(", "));
System.out.println(collectDistinct); //=> CO2, CH4, SO2
Espero entender su pregunta correctamente: asumiendo que los valores son de tipo String
, la forma más eficiente es probablemente convertir a HashSet
ay iterar sobre él:
ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
... //Do something
}
Esta es una forma sencilla sin recurrir a comparadores personalizados o cosas así:
Set<String> gasNames = new HashSet<String>();
List<YourRecord> records = ...;
for(YourRecord record : records) {
gasNames.add(record.getGasName());
}
// now gasNames is a set of unique gas names, which you could operate on:
List<String> sortedGasses = new ArrayList<String>(gasNames);
Collections.sort(sortedGasses);
Nota: Usar en TreeSet
lugar de HashSet
daría una lista de matrices ordenada directamente y la superior Collections.sort
podría omitirse , pero por TreeSet
lo demás es menos eficiente, por lo que a menudo es mejor, y rara vez peor, usar HashSet
incluso cuando se necesita ordenar.
Cuando estaba haciendo la misma consulta, tuve dificultades para ajustar las soluciones a mi caso, aunque todas las respuestas anteriores tienen buenas perspectivas.
Aquí hay una solución cuando uno tiene que adquirir una lista de objetos únicos, NO cadenas. Digamos que uno tiene una lista de objetos Record. Record
la clase solo tiene propiedades de tipo String
, NO propiedad de tipo int
. Aquí la implementación se hashCode()
vuelve difícil ya que se hashCode()
necesita devolver un int
.
La siguiente es una Record
clase de muestra .
public class Record{
String employeeName;
String employeeGroup;
Record(String name, String group){
employeeName= name;
employeeGroup = group;
}
public String getEmployeeName(){
return employeeName;
}
public String getEmployeeGroup(){
return employeeGroup;
}
@Override
public boolean equals(Object o){
if(o instanceof Record){
if (((Record) o).employeeGroup.equals(employeeGroup) &&
((Record) o).employeeName.equals(employeeName)){
return true;
}
}
return false;
}
@Override
public int hashCode() { //this should return a unique code
int hash = 3; //this could be anything, but I would chose a prime(e.g. 5, 7, 11 )
//again, the multiplier could be anything like 59,79,89, any prime
hash = 89 * hash + Objects.hashCode(this.employeeGroup);
return hash;
}
Como otros sugirieron anteriormente, la clase debe anular tanto equals()
el hashCode()
método como el para poder usarHashSet
.
Ahora, digamos, la lista de registros es allRecord
( List<Record> allRecord
).
Set<Record> distinctRecords = new HashSet<>();
for(Record rc: allRecord){
distinctRecords.add(rc);
}
Esto solo agregará los distintos registros al Hashset, distintos registros.
Espero que esto ayude.
Si tiene una matriz de algún tipo de objeto (bean), puede hacer esto:
List<aBean> gasList = createDuplicateGasBeans();
Set<aBean> uniqueGas = new HashSet<aBean>(gasList);
como dijo Mathias Schwarz anteriormente, pero debe proporcionar a su aBean los métodos hashCode()
y equals(Object obj)
eso se puede hacer fácilmente en Eclipse mediante un menú dedicado ' Generate hashCode() and equals()
' (mientras está en la clase de bean). Set evaluará los métodos anulados para discriminar objetos iguales.