Подтвердить что ты не робот

Как сохранить уникальный список на Java?

Как создать список уникальных/отличных объектов (без дубликатов) в Java?

Прямо сейчас я использую HashMap<String, Integer> чтобы сделать это, так как ключ перезаписан, и, следовательно, в конце мы можем получить HashMap.getKeySet() который будет уникальным. Но я уверен, что должен быть лучший способ сделать это, поскольку часть стоимости здесь теряется.

4b9b3361

Ответ 1

Вы можете использовать Set реализацию:

Информация из JAVADoc:

Коллекция, содержащая не повторяющиеся элементы. Более формально множества не содержат пары элементов e1 и e2 таких, что e1.equals(e2) и не более одного нулевого элемента. Как видно из его имени, этот интерфейс моделирует математическую абстрактную абстракцию.

Примечание. Следует проявлять большую осторожность, если изменяемые объекты используются в качестве заданных элементов. Поведение набора не указывается, если значение объекта изменяется таким образом, который влияет на равные сравнения, когда объект является элементом в наборе. Особый случай этого запрета состоит в том, что недопустимо, чтобы набор содержал себя как элемент.

Это реализация:

  • HashSet

    Этот класс предлагает постоянную производительность времени для основных операций (добавление, удаление, наличие и размер), предполагая, что функция хэша правильно распределяет элементы среди ведер. Для итерации по этому набору требуется время, пропорциональное сумме размера экземпляра HashSet (количество элементов) плюс "емкость" экземпляра HashMap подкачки (количество ковшей). Таким образом, очень важно не устанавливать слишком высокую начальную мощность (или слишком низкий коэффициент нагрузки), если важна итерационная производительность.

    При повторении HashSet порядок уступаемых элементов undefined.

  • LinkedHashSet

    Таблица хэш-таблицы и связанный список интерфейса Set, с предсказуемым порядком итерации. Эта реализация отличается от HashSet тем, что она поддерживает двусвязный список, проходящий через все его записи. Этот связанный список определяет порядок итераций, который представляет собой порядок, в котором элементы были вставлены в набор (порядок вставки). Обратите внимание, что порядок вставки не изменяется, если элемент повторно вставлен в набор. (Элемент e повторно вставлен в набор s, если s.add(e) вызывается, когда s.contains(e) возвращает true непосредственно перед вызовом.)

    Итак, вывод кода выше...

     Set<Integer> linkedHashSet = new LinkedHashSet<>();
     linkedHashSet.add(3);
     linkedHashSet.add(1);
     linkedHashSet.add(2);
    
     for (int i : linkedHashSet) {
         System.out.println(i);
     }
    

    ... обязательно будет

    3
    1
    2
    
  • TreeSet

    Эта реализация обеспечивает гарантированную log (n) временную стоимость для основных операций (добавление, удаление и содержит). По умолчанию элементы, возвращаемые на итерации, сортируются по их "естественному порядку, поэтому код выше...

     Set<Integer> treeSet = new TreeSet<>();
     treeSet.add(3);
     treeSet.add(1);
     treeSet.add(2);
    
     for (int i : treeSet) {
         System.out.println(i);
     }
    

    ... выведет это:

    1
    2
    3
    

    (Вы также можете передать экземпляр Comparator в конструктор TreeSet, чтобы отсортировать элементы в другом порядке.)

    Обратите внимание, что порядок, поддерживаемый набором (будь то явный компаратор), должен быть согласован с равными, если он правильно реализует интерфейс Set. (См. Comparable или Comparator для точного определения соответствия с равными.) Это происходит потому, что интерфейс Set определен в терминах операции equals, но экземпляр TreeSet выполняет все сравнения элементов с помощью метода compareTo (или сравнения), поэтому два элементы, которые по этому методу считаются равными, равны, с точки зрения множества. Поведение множества хорошо определено, даже если его упорядочение не соответствует равным; он просто не подчиняется генеральному контракту интерфейса Set.

Ответ 2

Я хочу прояснить некоторые вещи здесь для оригинального плаката, о котором другие упоминали, но на самом деле явно не заявляли. Когда вы говорите, что хотите уникальный список, это само определение упорядоченного набора. Некоторые другие ключевые отличия между интерфейсом Set Interface и List включают в себя то, что List позволяет указать индекс вставки. Итак, вопрос в том, действительно ли вам нужен интерфейс списка (т.е. Для совместимости с сторонней библиотекой и т.д.), Или вы можете перепроектировать ваше программное обеспечение для использования интерфейса Set? Вы также должны учитывать, что вы делаете с интерфейсом. Важно ли находить элементы по их индексу? Сколько элементов вы ожидаете в своем наборе? Если у вас будет много элементов, важно ли заказать?

Если вам действительно нужен Список, у которого только есть уникальное ограничение, есть класс Apache Common Utils org.apache.commons.collections.list.SetUniqueList, который предоставит вам интерфейс List и уникальное ограничение. Имейте в виду, что это нарушает интерфейс List. Тем не менее, вы получите лучшую производительность, если вам нужно искать в списке по индексу. Если вы можете иметь дело с интерфейсом Set, и у вас есть меньший набор данных, тогда LinkedHashSet может быть хорошим способом. Это просто зависит от дизайна и намерения вашего программного обеспечения.

Опять же, для каждой коллекции есть определенные преимущества и недостатки. Некоторые быстрые вставки, но медленные чтения, некоторые из них быстро читают, но медленные вставки и т.д. Имеет смысл потратить много времени на сборку документации, чтобы полностью узнать о более тонких деталях каждого класса и интерфейса.

Ответ 3

Используйте new HashSet<String> Пример:

import java.util.HashSet;
import java.util.Set;

public class MainClass {
  public static void main(String args[]) {
    String[] name1 = { "Amy", "Jose", "Jeremy", "Alice", "Patrick" };

    String[] name2 = { "Alan", "Amy", "Jeremy", "Helen", "Alexi" };

    String[] name3 = { "Adel", "Aaron", "Amy", "James", "Alice" };

    Set<String> letter = new HashSet<String>();

    for (int i = 0; i < name1.length; i++)
      letter.add(name1[i]);

    for (int j = 0; j < name2.length; j++)
      letter.add(name2[j]);

    for (int k = 0; k < name3.length; k++)
      letter.add(name3[k]);

    System.out.println(letter.size() + " letters must be sent to: " + letter);

  }
}

Ответ 4

Вы можете просто использовать HashSet<String> для поддержки коллекции уникальных объектов. Если значения Integer на вашей карте важны, вы можете вместо этого использовать метод карт containsKey, чтобы проверить, находится ли ваш ключ уже на карте.

Ответ 5

HashSet<String> (или) любая реализация Set может выполнить эту работу для вас. Set не позволяют дублировать.

Вот javadoc для HashSet.

Ответ 6

Я не знаю, насколько это эффективно, однако работал для меня в простом контексте.

List<int> uniqueNumbers = new ArrayList<>();

   public void AddNumberToList(int num)
    {
        if(!uniqueNumbers .contains(num)) {
            uniqueNumbers .add(num);
        }
    }

Ответ 7

Возможно, вы захотите использовать один из классов реализации java.util.Set<E> Interface, например. java.util.HashSet<String> класс коллекции.

Коллекция, которая не содержит повторяющихся элементов. Более формально множества не содержат пары элементов e1 и e2 таких, что e1.equals(e2) и не более одного нулевого элемента. Как видно из его названия, этот интерфейс моделирует математическую абстрактную абстракцию.

Ответ 8

Я.АЛИ

list = new ArrayList<>(new HashSet<>(list));