Mam ArrayListkilka 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 ArrayListkilka 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 Setto kolekcja, która nie zawiera duplikatów.
Jeśli masz, Listktó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 HashSetkonstruktor 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 HashSeti 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 TreeSetzamiast tego HashSetdałoby bezpośrednio posortowaną listę arraylist i wyższe, Collections.sortktóre można pominąć, ale TreeSetpoza tym jest mniej wydajne, więc często lepiej, a rzadko gorzej, używać HashSetnawet 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. Recordklasa 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 Recordklasa.
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.