web-dev-qa-db-fra.com

Obtenez des valeurs uniques d'arraylist en java

J'ai une ArrayList avec un certain nombre d'enregistrements et une colonne contenant des noms de gaz comme CO2 CH4 SO2, etc. Maintenant, je veux récupérer différents noms de gaz (uniques) uniquement sans interprétation de la ArrayList. Comment ceci peut être fait?

58
SDas

Vous devriez utiliser un Set .

Un ensemble est un Collection qui ne contient aucun doublon.

Si vous avez une List qui contient des doublons, vous pouvez obtenir les entrées uniques comme ceci:

List<String> gasList = // create list with duplicates...
Set<String> uniqueGas = new HashSet<String>(gasList);
System.out.println("Unique gas count: " + uniqueGas.size());

NOTE: ce constructeur HashSet identifie les doublons en appelant les méthodes 'equals () des éléments.

96
jahroy

Vous pouvez utiliser API Java 8 Stream .

Méthode distinct est une opération intermediate qui filtre le flux et permet uniquement aux valeurs de distict (par défaut avec la méthode Object :: equals) de passer à l'opération suivante.
J'ai écrit un exemple ci-dessous pour votre cas, 

// 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
47

J'espère que j'ai bien compris votre question: en supposant que les valeurs sont de type String, le moyen le plus efficace est probablement de convertir en une HashSet et d'itérer dessus:

ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
   ... //Do something
}
10
Mathias Schwarz
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique
6
xagyg

Voici un moyen simple sans recourir à des comparateurs personnalisés ou à des choses comme ça:

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);

Remarque: L'utilisation de TreeSet au lieu de HashSet donnerait une liste triée directement et une liste supérieure à Collections.sort pourrait être omise, mais TreeSet est autrement moins efficace, il est donc souvent préférable, et même pire, d'utiliser HashSet même lorsque le tri est nécessaire.

6
hyde

Si vous avez un tableau d'un type d'objet (bean), vous pouvez le faire:

List<aBean> gasList = createDuplicateGasBeans();
Set<aBean> uniqueGas = new HashSet<aBean>(gasList);

comme dit Mathias Schwarz ci-dessus, mais vous devez fournir à votre aBean les méthodes hashCode() et equals(Object obj) qui peuvent être effectuées facilement dans Eclipse via le menu dédié 'Generate hashCode() and equals()' (dans la classe de bean) . Set évaluera les méthodes remplacées par discriminer les objets égaux.

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

n'oubliez pas de mettre en œuvre votre méthode equals

1
Santoferr

vous pouvez l'utiliser pour créer une liste Unique

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

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

Lorsque j'ai posé la même question, j'ai eu du mal à adapter les solutions à mon cas, bien que toutes les réponses précédentes comportent de bonnes idées. 

Voici une solution lorsqu'il faut acquérir une liste d'objets uniques, PAS de chaînes. Disons qu’on a une liste d’objets Record. Record class n'a que des propriétés de type String, NO des propriétés de type int. Ici, implémenter hashCode() devient difficile car hashCode() doit renvoyer une int.

Voici un exemple de classe Record.

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;
    }

Comme d'autres l'ont déjà suggéré, la classe doit remplacer les méthodes equals() et hashCode() pour pouvoir utiliser HashSet.

Maintenant, disons, la liste des enregistrements est allRecord (List<Record> allRecord). 

Set<Record> distinctRecords = new HashSet<>();

for(Record rc: allRecord){
    distinctRecords.add(rc);
}

Cela ne fera qu'ajouter les enregistrements distincts au hachage, distinctRecords.

J'espère que cela t'aides.

0
Natasha