Лучший способ получить уникальный список без изменения заказа - PullRequest
1 голос
/ 05 июля 2019

У меня есть список строк или список целых чисел из 20 000 элементов

Теперь он содержит дубликаты ... Однако я не хочу нарушать порядок элементов.

Мыможет легко преобразовать список в Set для уникального Set unique = new HashSet (list);

Однако вышеприведенное нарушает последовательный порядок элементов.

Каков наилучший подход для этого?

Спасибо.

Ответы [ 5 ]

2 голосов
/ 05 июля 2019

Вы должны использовать java.util.LinkedHashSet , чтобы получить уникальные элементы без изменения порядка:

Set<String> uniqueSet = new LinkedHashSet<>(list);

Еще один способ - использовать distinct():

list.stream().distinct().collect(Collectors.toList())

Но distinct() использует LinkedHashSet внутри.Нет необходимости в ненужной процедуре.

Поэтому наилучшим способом является использование конструктора LinkedHashSet:

LinkedHashSet (Коллекция c) Создает новый связанный хэш-набор с теми же элементами, что и указанная коллекция.

0 голосов
/ 05 июля 2019

Попробуйте приведенный ниже код

    public static void main(String[] args) {
    String list[] = {"9","1","1","9","2","7","2"};
    List<String> unique = new ArrayList<>();

    for(int i=0; i<list.length; i++) {
        int count = unique.size();

        if(count==0) {
            unique.add(list[i]);
        }else {
            boolean available = false;
            for(int j=0; j<count; j++) {
                if(unique.get(j).equals(list[i])) {
                    available = true;
                    break;
                }
            }

            if(!available) {
                unique.add(list[i]);
            }
        }
    }

    //checking latest 'unique' value
    for(int i=0; i<unique.size(); i++) {
        System.out.println(unique.get(i));
    }

}

Возвращается 9 1 2 7, но я не пробовал до 20 000 списков сбора, надеюсь, проблем с производительностью нет

0 голосов
/ 05 июля 2019

Вы можете попробовать поток distinct

yourList.stream().distinct().collect(Collectors.toList());

Update1 : Насколько я знаю, это лучшее решение.

  1. list.contains(element) выполнит 2 цикла. Один для итерации элемента и добавления его в новый список, один для проверки элемента содержится -> 0 (n * n)

  2. new LinkedHashSet() создаст новый LinkedHashSet и новый выход Arraylist -> проблема с памятью. И производительность, я думаю, что это равно stream distinct

Update2 : мы должны убедиться, что выходной сигнал равен List, а не Set

  1. Как я знаю, stream distinct использует HashSet внутри страны. В нашем случае это более эффективная реализация памяти, чем LinkedHashSet (которая представляет собой реализацию хеш-таблицы и связанного списка для интерфейса установки). Подробнее здесь
  2. Если вы примените LinkedHashSet, исходный код будет примерно таким, как показано ниже, поэтому у нас есть 1 ArrayList и 1 LinkedHashSet.

    output = new ArrayList (новый LinkedHashSet (yourList));

  3. Я сделал небольшой тест с циклом 1k.

int size = 1000000;
Random rand = new Random((int) (System.currentTimeMillis() / 1000));
List<Integer> yourList = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
    yourList.add(rand.nextInt(10000));
}
// test1: LinkedHashSet --> 35ms
new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList));
// test2: Stream distinct --> 30ms
yourList.stream().distinct().collect(Collectors.toList());

0 голосов
/ 05 июля 2019

Если вы не хотите нарушать порядок, выполните итерацию списка и создайте новый список, как показано ниже.

    ArrayList<Integer> newList = new ArrayList<Integer>();       
    for (Integer element : list) { 
        if (!newList.contains(element)) {       
            newList.add(element); 
        } 
    }
0 голосов
/ 05 июля 2019

Если вы пытаетесь устранить дубликаты, вы можете использовать LinkedHashSet, он будет поддерживать порядок.

если строка

Set<String> dedupSet = new LinkedHashSet<>();

если целое число

Set<Integer> dedupSet = new LinkedHashSet<>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...