У мене є ArrayList
декілька записів, і одна колонка містить назви газів як CO2 CH4 SO2 тощо. Тепер я хочу отримати різні назви газів (унікальні) лише без повторення з ArrayList
. Як це можна зробити?
У мене є ArrayList
декілька записів, і одна колонка містить назви газів як CO2 CH4 SO2 тощо. Тепер я хочу отримати різні назви газів (унікальні) лише без повторення з ArrayList
. Як це можна зробити?
Відповіді:
Ви повинні використовувати a Set
. A Set
- це колекція, яка не містить дублікатів.
Якщо у вас є List
копія, яка містить дублікати, ви можете отримати такі унікальні записи:
List<String> gasList = // create list with duplicates...
Set<String> uniqueGas = new HashSet<String>(gasList);
System.out.println("Unique gas count: " + uniqueGas.size());
ПРИМІТКА . Цей HashSet
конструктор ідентифікує дублікати за допомогою методів equals () елементів .
java: no suitable constructor found for HashSet
. Будь-яка ідея, чому це відбувається?
LinkedHashSet
stackoverflow.com/a/8712770/32453
Метод відмінності - це проміжна операція, яка фільтрує потік і дозволяє лише різним значенням (за замовчуванням використовується метод Object :: equals) переходити до наступної операції.
Я написав нижче приклад для вашої справи,
// 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
Сподіваюся, я правильно зрозумів ваше запитання: припускаючи, що значення мають тип String
, найефективніший спосіб - це, мабуть, перетворення в a HashSet
і ітерацію над ним:
ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
... //Do something
}
Ось прямий спосіб, не вдаючись до користувацьких порівняльників або подібних речей:
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);
Примітка: Використання TreeSet
замість HashSet
дасть безпосередньо відсортований арраліст і вище, Collections.sort
його можна пропустити, але TreeSet
в іншому випадку це менш ефективно, тому його часто краще і рідше гірше використовувати HashSet
навіть тоді, коли потрібно сортування.
Ви можете використовувати це для створення списку Унікальним
ArrayList<String> listWithDuplicateValues = new ArrayList<>();
list.add("first");
list.add("first");
list.add("second");
ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());
Коли я робив той самий запит, мені було важко пристосувати рішення до мого випадку, хоча всі попередні відповіді мають хороші уявлення.
Ось рішення, коли потрібно отримати список унікальних об’єктів, а НЕ рядків. Скажімо, у одного є список об’єкта Record. Record
клас має лише властивості type String
, NO властивість type int
. Тут реалізація hashCode()
стає важкою, оскільки hashCode()
потрібно повернути файлint
.
Далі наведено зразок 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;
}
Як пропонувалося раніше іншими, клас повинен замінити як метод, так equals()
і hashCode()
метод, щоб мати можливість використовуватиHashSet
.
Тепер, скажімо, список записів allRecord
( List<Record> allRecord
).
Set<Record> distinctRecords = new HashSet<>();
for(Record rc: allRecord){
distinctRecords.add(rc);
}
Це лише додасть окремі записи в хешсет, distinctRecords.
Сподіваюся, це допомагає.
Якщо у вас є масив якогось об’єкта (bean), ви можете зробити це:
List<aBean> gasList = createDuplicateGasBeans();
Set<aBean> uniqueGas = new HashSet<aBean>(gasList);
як сказав Матіас Шварц вище, але ви повинні надати своєму aBean методи, hashCode()
і equals(Object obj)
це можна легко зробити в Eclipse за допомогою спеціального меню ' Generate hashCode() and equals()
' (в той час як у класі Bean ). Set оцінить перевизначені методи для розрізнення рівних об'єктів.