Mam ArrayList
kilka rekordów, a jedna kolumna zawiera nazwy gazów, takie jak CO2 CH4 SO2 itp. Teraz chcę pobrać różne nazwy gazów (unikalne) tylko bez powtarzania z ArrayList
. Jak można to zrobić?
Mam ArrayList
kilka rekordów, a jedna kolumna zawiera nazwy gazów, takie jak CO2 CH4 SO2 itp. Teraz chcę pobrać różne nazwy gazów (unikalne) tylko bez powtarzania z ArrayList
. Jak można to zrobić?
Odpowiedzi:
Powinieneś użyć Set
. A Set
to kolekcja, która nie zawiera duplikatów.
Jeśli masz, List
który zawiera duplikaty, możesz uzyskać unikalne wpisy w ten sposób:
List<String> gasList = // create list with duplicates...
Set<String> uniqueGas = new HashSet<String>(gasList);
System.out.println("Unique gas count: " + uniqueGas.size());
UWAGA : Ten HashSet
konstruktor identyfikuje duplikaty, wywołując metody equals () elementów .
java: no suitable constructor found for HashSet
. Masz jakiś pomysł, dlaczego tak się dzieje?
LinkedHashSet
stackoverflow.com/a/8712770/32453
Metoda odrębna to operacja pośrednia, która filtruje strumień i pozwala tylko odrębnym wartościom (domyślnie przy użyciu metody Object :: equals) przejść do następnej operacji.
Poniżej napisałem przykład dla twojego przypadku,
// 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
Mam nadzieję, że dobrze rozumiem twoje pytanie: zakładając, że wartości są typu String
, najskuteczniejszym sposobem jest prawdopodobnie zamiana na a HashSet
i iteracja po nim:
ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
... //Do something
}
Oto prosty sposób bez uciekania się do niestandardowych komparatorów lub podobnych rzeczy:
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);
Uwaga: użycie TreeSet
zamiast tego HashSet
dałoby bezpośrednio posortowaną listę arraylist i wyższe, Collections.sort
które można pominąć, ale TreeSet
poza tym jest mniej wydajne, więc często lepiej, a rzadko gorzej, używać HashSet
nawet wtedy, gdy potrzebne jest sortowanie.
Kiedy robiłem to samo zapytanie, miałem trudności z dostosowaniem rozwiązań do mojego przypadku, chociaż wszystkie poprzednie odpowiedzi mają dobry wgląd.
Oto rozwiązanie, gdy trzeba uzyskać listę unikalnych obiektów, a nie ciągów. Powiedzmy, że mamy listę obiektów Record. Record
klasa ma tylko właściwości typu String
, BRAK właściwości typu int
. Tutaj implementacja hashCode()
staje się trudna, ponieważ hashCode()
trzeba zwrócić plik int
.
Poniżej znajduje się przykładowa Record
klasa.
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;
}
Jak zasugerowali wcześniej inni, klasa musi przesłonić zarówno metodę, jak equals()
i hashCode()
metodę, aby móc jej używać HashSet
.
Powiedzmy, że lista rekordów to allRecord
( List<Record> allRecord
).
Set<Record> distinctRecords = new HashSet<>();
for(Record rc: allRecord){
distinctRecords.add(rc);
}
Spowoduje to tylko dodanie odrębnych rekordów do skrótu, odrębnych rekordów.
Mam nadzieję że to pomoże.
Jeśli masz tablicę jakiegoś obiektu (fasoli), możesz to zrobić:
List<aBean> gasList = createDuplicateGasBeans();
Set<aBean> uniqueGas = new HashSet<aBean>(gasList);
jak powiedział Mathias Schwarz powyżej, ale musisz dostarczyć swojemu aBean metodami hashCode()
i equals(Object obj)
można to łatwo zrobić w Eclipse przez dedykowane menu ' Generate hashCode() and equals()
' (będąc w klasie bean). Set oceni nadpisane metody w celu rozróżnienia równych obiektów.