Obtenga valores únicos de arraylist en java

81

Tengo una ArrayListcon 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?

SDas
fuente
4
Actualizaré las etiquetas. Esta es una pregunta de Java y creo que no está relacionada con jsf y primefaces ...
Mathias Schwarz

Respuestas:

133

Debería utilizar un Set. A Setes una colección que no contiene duplicados.

Si tiene un Listque 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 HashSetconstructor identifica duplicados invocando los métodos equals () de los elementos .

jahroy
fuente
eso implica que 2 registros se consideran iguales (en el sentido de HashSet) si sus nombres son iguales.
njzk2
@ njzk2 - Pensé que sería bastante obvio, pero creo que puedo editar para señalarlo explícitamente ...
jahroy
Me aparece un error al intentar ejecutar el código anterior: java: no suitable constructor found for HashSet. ¿Alguna idea de por qué ocurre esto?
lordlabakdas
66

Puede utilizar Java 8 Stream API .

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
George Siggouroglou
fuente
11

Espero entender su pregunta correctamente: asumiendo que los valores son de tipo String, la forma más eficiente es probablemente convertir a HashSetay iterar sobre él:

ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
   ... //Do something
}
Mathias Schwarz
fuente
6
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique
xagyg
fuente
Ahora obtengo los elementos únicos de la lista, pero se está ordenando por sí solo. Pero necesito que los datos no estén ordenados. ¿Cómo se puede hacer?
SDas
6

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 TreeSetlugar de HashSetdaría una lista de matrices ordenada directamente y la superior Collections.sortpodría omitirse , pero por TreeSetlo demás es menos eficiente, por lo que a menudo es mejor, y rara vez peor, usar HashSetincluso cuando se necesita ordenar.

Hyde
fuente
3

puede usar esto para hacer una lista única

ArrayList<String> listWithDuplicateValues = new ArrayList<>();
list.add("first");
list.add("first");
list.add("second");

ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());
Nitin9791
fuente
2

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. Recordla 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 Recordclase 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.

Natasha
fuente
1

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.

Salvatore D'alessandro
fuente
1
  @SuppressWarnings({ "unchecked", "rawtypes" })
    public static List getUniqueValues(List input) {
    return new ArrayList<>(new HashSet<>(input));
    }

no olvides implementar tu método de iguales

Santoferr
fuente