web-dev-qa-db-ger.com

Erhalten Sie eindeutige Werte aus der Arrayliste in Java

Ich habe eine ArrayList mit einer Reihe von Datensätzen und eine Spalte enthält Gasnamen wie CO2 CH4 SO2 usw. Nun möchte ich verschiedene Gasnamen (eindeutig) nur ohne Wiederholung aus der ArrayList abrufen. Wie geht das?

58
SDas

Sie sollten ein Set verwenden.

Ein Set ist ein Collection , das keine Duplikate enthält.

Wenn Sie eine Liste haben, die Duplikate enthält, können Sie die eindeutigen Einträge wie folgt erhalten:

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

NOTE: Dieser HashSet-Konstruktor identifiziert Duplikate, indem er die equals () -Methoden der Elemente aufruft.

105
jahroy

Sie können Java 8 Stream API verwenden.

Die Methode distinct ist eine intermediäre Operation, die den Stream filtert und nur Werte trennen lässt (standardmäßig mithilfe der Object :: equals-Methode), um an die nächste Operation zu übergeben.
Ich habe unten ein Beispiel für Ihren Fall geschrieben, 

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

Ich hoffe, ich verstehe Ihre Frage richtig: Wenn Sie annehmen, dass die Werte vom Typ String sind, ist der effizienteste Weg wahrscheinlich die Umwandlung in eine HashSet und eine Iteration darüber:

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

Hier ist ein einfacher Weg, ohne auf benutzerdefinierte Vergleicher oder ähnliches zurückgreifen zu müssen:

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

Hinweis: Die Verwendung von TreeSet anstelle von HashSet würde zu einer direkt sortierten Arrayliste führen, und Collections.sort könnte übersprungen werden. Andernfalls ist TreeSet weniger effizient. Daher ist es oft besser und selten schlechter, HashSet zu verwenden, selbst wenn eine Sortierung erforderlich ist.

6
hyde

Wenn Sie ein Array mit einem Objekt (Bean) haben, können Sie Folgendes tun:

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

wie bereits oben von Mathias Schwarz beschrieben, aber Sie müssen Ihrem aBean die Methoden hashCode() und equals(Object obj) zur Verfügung stellen, die in Eclipse einfach über das dedizierte Menü 'Generate hashCode() and equals()' (in der Bean-Klasse) ... durchgeführt werden können Gleiche Objekte unterscheiden.

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

vergessen Sie nicht, Ihre Equals-Methode zu implementieren

1
Santoferr

sie können dies verwenden, um eine Liste eindeutig zu machen

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

Bei der gleichen Abfrage fiel es mir schwer, die Lösungen an meinen Fall anzupassen, obwohl alle vorherigen Antworten gute Einsichten haben. 

Hier ist eine Lösung, wenn Sie eine Liste eindeutiger Objekte und KEINE Zeichenketten erwerben müssen. Nehmen wir an, man hat eine Liste von Record-Objekten. Die Klasse Record hat nur Eigenschaften des Typs String, NO die Eigenschaft des Typs int. Hier wird die Implementierung von hashCode() schwierig, da hashCode() eine int zurückgeben muss.

Das folgende Beispiel zeigt eine Record-Klasse.

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

Wie bereits von anderen vorgeschlagen, muss die Klasse sowohl die equals()- als auch die hashCode()-Methode überschreiben, um HashSet verwenden zu können.

Nehmen wir an, die Liste der Datensätze lautet allRecord (List<Record> allRecord). 

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

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

Dadurch werden nur die eindeutigen Datensätze zu dem Hashset distinctRecords hinzugefügt.

Hoffe das hilft.

0
Natasha