Отримайте унікальні значення від arraylist у Java


83

У мене є ArrayListдекілька записів, і одна колонка містить назви газів як CO2 CH4 SO2 тощо. Тепер я хочу отримати різні назви газів (унікальні) лише без повторення з ArrayList. Як це можна зробити?


4
Я оновлю теги. Це питання Java, і я вважаю, що воно не пов’язане з jsf та праймфейсами ...
Матіас Шварц,

Відповіді:


136

Ви повинні використовувати 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 () елементів .


це означає, що 2 записи вважаються рівними (у розумінні HashSet), якщо їх імена рівні.
njzk2

@ njzk2 - Я вважав, що це буде досить очевидно, але, мабуть, я можу редагувати, щоб чітко вказати на це ...
jahroy

Я отримую повідомлення про помилку при спробі реалізувати код вище: java: no suitable constructor found for HashSet. Будь-яка ідея, чому це відбувається?
lordlabakdas

Якщо ви хочете зберегти оригінальний замовлення зі списку см LinkedHashSet stackoverflow.com/a/8712770/32453
rogerdpack

68

Ви можете використовувати Java 8 Stream API .

Метод відмінності - це проміжна операція, яка фільтрує потік і дозволяє лише різним значенням (за замовчуванням використовується метод 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

12

Сподіваюся, я правильно зрозумів ваше запитання: припускаючи, що значення мають тип String, найефективніший спосіб - це, мабуть, перетворення в a HashSetі ітерацію над ним:

ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
   ... //Do something
}

6
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique

Зараз я отримую унікальні елементи зі списку, але він сортується сам по собі, але мені потрібно, щоб дані не були впорядковані. Як це можна зробити?
SDas

6

Ось прямий спосіб, не вдаючись до користувацьких порівняльників або подібних речей:

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навіть тоді, коли потрібно сортування.


3

Ви можете використовувати це для створення списку Унікальним

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

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

2

Коли я робив той самий запит, мені було важко пристосувати рішення до мого випадку, хоча всі попередні відповіді мають хороші уявлення.

Ось рішення, коли потрібно отримати список унікальних об’єктів, а НЕ рядків. Скажімо, у одного є список об’єкта 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.

Сподіваюся, це допомагає.


2
    public static List getUniqueValues(List input) {
      return new ArrayList<>(new LinkedHashSet<>(incoming));
    }

не забудьте спочатку застосувати ваш метод equals


1

Якщо у вас є масив якогось об’єкта (bean), ви можете зробити це:

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

як сказав Матіас Шварц вище, але ви повинні надати своєму aBean методи, hashCode()і equals(Object obj)це можна легко зробити в Eclipse за допомогою спеціального меню ' Generate hashCode() and equals()' (в той час як у класі Bean ). Set оцінить перевизначені методи для розрізнення рівних об'єктів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.