Удалите дубликаты элементов из ArrayList, которые составляют Collection [duplicate]

Компиляция программы на C ++ выполняется в несколько этапов, как указано в 2.2 (кредиты для Кейта Томпсона для ссылки) :

Превалирование среди правил синтаксиса

  1. Физические символы исходного файла сопоставляются в соответствии с реализацией в соответствии с базовым набором символов источника (ввод символов новой строки для индикаторов конца строки) при необходимости. [SNIP]
  2. Каждый экземпляр символа обратной косой черты (\), за которым сразу следует символ новой строки, удаляется, сплайсируя физические исходные строки для формирования логических строк источника. [SNIP]
  3. Исходный файл разбивается на токены предварительной обработки (2.5) и последовательности символов пробела (включая комментарии). [SNIP]
  4. Выполнены предпроцессорные директивы, макро-вызовы разворачиваются и выполняются операторные выражения _Pragma. [SNIP]
  5. Каждый элемент набора символов в символьном литерале или строковый литерал, а также каждая escape-последовательность и универсальное имя-символа в символьном литерале или не- -raw строковый литерал, преобразуется в соответствующий член набора символов выполнения; [SNIP]
  6. Соединительные маркеры литералов строки объединены.
  7. Символы пробела, разделяющие токены, уже не являются значимыми. Каждый токен предварительной обработки преобразуется в токен. (2.7). Результирующие маркеры синтаксически и семантически анализируются и переводятся как единица перевода. [SNIP]
  8. Устанавливаемые единицы перевода и единицы экземпляра объединяются следующим образом: [SNIP]
  9. Все ссылки на внешние сущности решена. Компоненты библиотеки связаны для удовлетворения внешних ссылок на объекты, не определенные в текущем переводе. Весь такой переводчик выводится в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения. (акцент мой)

[footnote] Реализации должны вести себя так, как если бы эти отдельные фазы происходили, хотя на практике различные фазы могли быть свернуты вместе.

Указанные ошибки возникают на этом последнем этапе компиляции, чаще всего называемом связыванием. Это в основном означает, что вы собрали кучу файлов реализации в объектные файлы или библиотеки, и теперь вы хотите заставить их работать вместе.

Скажите, что вы определили символ a в a.cpp. Теперь b.cpp объявил этот символ и использовал его. Перед связыванием он просто предполагает, что этот символ был определен где-то , но он пока не заботится о том, где. Фаза связывания отвечает за поиск символа и правильную привязку его к b.cpp (ну, собственно, к объекту или библиотеке, которая его использует).

Если вы используете Microsoft Visual Studio, вы будете см., что проекты генерируют файлы .lib. Они содержат таблицу экспортированных символов и таблицу импортированных символов. Импортированные символы разрешены против библиотек, на которые вы ссылаетесь, и экспортированные символы предоставляются для библиотек, которые используют этот .lib (если есть).

Подобные механизмы существуют для других компиляторов / платформ.

Общие сообщения об ошибках: error LNK2001, error LNK1120, error LNK2019 для Microsoft Visual Studio и undefined reference to symbolName для GCC.

Код:

struct X
{
   virtual void foo();
};
struct Y : X
{
   void foo() {}
};
struct A
{
   virtual ~A() = 0;
};
struct B: A
{
   virtual ~B(){}
};
extern int x;
void foo();
int main()
{
   x = 0;
   foo();
   Y y;
   B b;
}

генерирует следующие ошибки с GCC:

/home/AbiSfw/ccvvuHoX.o: In function `main':
prog.cpp:(.text+0x10): undefined reference to `x'
prog.cpp:(.text+0x19): undefined reference to `foo()'
prog.cpp:(.text+0x2d): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD1Ev[B::~B()]+0xb): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o: In function `B::~B()':
prog.cpp:(.text._ZN1BD0Ev[B::~B()]+0x12): undefined reference to `A::~A()'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1Y[typeinfo for Y]+0x8): undefined reference to `typeinfo for X'
/home/AbiSfw/ccvvuHoX.o:(.rodata._ZTI1B[typeinfo for B]+0x8): undefined reference to `typeinfo for A'
collect2: ld returned 1 exit status

и аналогичные ошибки с Microsoft Visual Studio:

1>test2.obj : error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)
1>test2.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ)
1>test2.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall X::foo(void)" (?foo@X@@UAEXXZ)
1>...\test2.exe : fatal error LNK1120: 4 unresolved externals

. Общие причины включают в себя:

407
задан Jonik 29 August 2013 в 08:28
поделиться

30 ответов

856
ответ дан Andrew Tobilko 28 August 2018 в 10:36
поделиться

Код:

List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);

Примечание: Определенно, накладные расходы памяти.

2
ответ дан almightyGOSU 28 August 2018 в 10:36
поделиться

Если вы не хотите дубликатов, используйте Установить вместо List. Чтобы преобразовать List в Set, вы можете использовать следующий код:

// list is some List of Strings
Set<String> s = new HashSet<String>(list);

Если действительно необходимо, вы можете использовать ту же конструкцию, чтобы преобразовать Set обратно в List.

50
ответ дан Benno Richters 28 August 2018 в 10:36
поделиться

Можно удалить дубликаты из arraylist без использования HashSet или еще одного arraylist.

Попробуйте этот код ..

    ArrayList<String> lst = new ArrayList<String>();
    lst.add("ABC");
    lst.add("ABC");
    lst.add("ABCD");
    lst.add("ABCD");
    lst.add("ABCE");

    System.out.println("Duplicates List "+lst);

    Object[] st = lst.toArray();
      for (Object s : st) {
        if (lst.indexOf(s) != lst.lastIndexOf(s)) {
            lst.remove(lst.lastIndexOf(s));
         }
      }

    System.out.println("Distinct List "+lst);

Выход:

Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
20
ответ дан CarlJohn 28 August 2018 в 10:36
поделиться

В Java 8:

List<String> deduped = list.stream().distinct().collect(Collectors.toList());

Обратите внимание, что контракт hashCode-equals для членов списка должен соблюдаться для правильной работы фильтрации.

89
ответ дан Community 28 August 2018 в 10:36
поделиться

Если вы хотите использовать стороннюю библиотеку, вы можете использовать метод distinct() в Eclipse Collections (ранее GS Collections).

ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
    FastList.newListWith(1, 3, 2),
    integers.distinct());

Преимущество использования distinct() вместо преобразования в набор, а затем обратно в список состоит в том, что distinct() сохраняет порядок исходного списка, сохраняя первое вхождение каждого элемента.

MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
    T item = list.get(i);
    if (seenSoFar.add(item))
    {
        targetCollection.add(item);
    }
}
return targetCollection;

Если вы не можете преобразовать исходный список в тип коллекций Eclipse, вы можете использовать ListAdapter для получения того же API.

MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();

Примечание: я являюсь коммиттером для коллекций Eclipse.

5
ответ дан Donald Raab 28 August 2018 в 10:36
поделиться
for(int a=0;a<myArray.size();a++){
        for(int b=a+1;b<myArray.size();b++){
            if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
                myArray.remove(b); 
                dups++;
                b--;
            }
        }
}
0
ответ дан Ghyour 28 August 2018 в 10:36
поделиться

Если вы используете тип модели List & lt; Т> / ArrayList & л; T>. Надеюсь, это поможет вам.


Вот мой код без использования какой-либо другой структуры данных, такой как set или hashmap

for(int i = 0; i < Models.size(); i++) {
     for(int j = i + 1; j < Models.size(); j++) {                                
       if(Models.get(i).getName().equals(Models.get(j).getName())){    
                                Models.remove(j);

                                j--;
                            }
                        }
                    }
1
ответ дан Gufran Hasan 28 August 2018 в 10:36
поделиться

вы можете использовать вложенный цикл:

ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();

        Iterator iterator1 = l1.iterator();
        boolean repeated = false;

        while (iterator1.hasNext())
        {
            Class1 c1 = (Class1) iterator1.next();
            for (Class1 _c: l2) {
                if(_c.getId() == c1.getId())
                    repeated = true;
            }
            if(!repeated)
                l2.add(c1);
        }
1
ответ дан HamidReza 28 August 2018 в 10:36
поделиться

Вот способ, который не влияет на упорядочение списка:

ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();

Iterator iterator = l1.iterator();

        while (iterator.hasNext())
        {
            YourClass o = (YourClass) iterator.next();
            if(!l2.contains(o)) l2.add(o);
        }

l1 является исходным списком, а l2 - списком без повторных элементов (убедитесь, что у YourClass есть метод equals, соответствующий тому, что вы хотите стоять за равенство)

25
ответ дан Hardik Joshi 28 August 2018 в 10:36
поделиться
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");

HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
2
ответ дан hardip 28 August 2018 в 10:36
поделиться
0
ответ дан Harsha 28 August 2018 в 10:36
поделиться

Хотя преобразование ArrayList в HashSet эффективно удаляет дубликаты, если вам нужно сохранить порядок вставки, я предпочел бы вам использовать этот вариант

// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);

Тогда, если вы необходимо вернуть ссылку List, вы можете снова использовать конструктор преобразования.

265
ответ дан Igor Ganapolsky 28 August 2018 в 10:36
поделиться

Потоки Java 8 обеспечивают очень простой способ удаления повторяющихся элементов из списка. Используя отличный метод. Если у нас есть список городов, и мы хотим удалить дубликаты из этого списка, это можно сделать в одной строке -

 List<String> cityList = new ArrayList<>();
 cityList.add("Delhi");
 cityList.add("Mumbai");
 cityList.add("Bangalore");
 cityList.add("Chennai");
 cityList.add("Kolkata");
 cityList.add("Mumbai");

 cityList = cityList.stream().distinct().collect(Collectors.toList());

Как удалить повторяющиеся элементы из arraylist

21
ответ дан infoj 28 August 2018 в 10:36
поделиться

Предположим, что у нас есть список String, например:

List<String> strList = new ArrayList<>(5);
// insert up to five items to list.        

. Затем мы можем удалить повторяющиеся элементы несколькими способами.

До Java 8

List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));

Использование Guava

List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));

Использование Java 8

List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());

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

32
ответ дан i_am_zero 28 August 2018 в 10:36
поделиться
1
ответ дан KIN 28 August 2018 в 10:36
поделиться

Эти три строки кода могут удалить дублированный элемент из ArrayList или любой коллекции.

List<Entity> entities = repository.findByUserId(userId);

Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
3
ответ дан M Kaweepatt Churcharoen 28 August 2018 в 10:36
поделиться
public static void main(String[] args){
    ArrayList<Object> al = new ArrayList<Object>();
    al.add("abc");
    al.add('a');
    al.add('b');
    al.add('a');
    al.add("abc");
    al.add(10.3);
    al.add('c');
    al.add(10);
    al.add("abc");
    al.add(10);
    System.out.println("Before Duplicate Remove:"+al);
    for(int i=0;i<al.size();i++){
        for(int j=i+1;j<al.size();j++){
            if(al.get(i).equals(al.get(j))){
                al.remove(j);
                j--;
            }
        }
    }
    System.out.println("After Removing duplicate:"+al);
}
10
ответ дан Manash Ranjan Dakua 28 August 2018 в 10:36
поделиться

Когда вы заполняете ArrayList, используйте условие для каждого элемента. Например:

    ArrayList< Integer > al = new ArrayList< Integer >(); 

    // fill 1 
    for ( int i = 0; i <= 5; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    // fill 2 
    for (int i = 0; i <= 10; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    for( Integer i: al )
    {
        System.out.print( i + " ");     
    }

Получим массив {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

2
ответ дан MantaMan 28 August 2018 в 10:36
поделиться

Вы также можете сделать это таким образом и сохранить порядок:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
20
ответ дан Nenad Bulatovic 28 August 2018 в 10:36
поделиться
import java.util.*;
class RemoveDupFrmString
{
    public static void main(String[] args)
    {

        String s="appsc";

        Set<Character> unique = new LinkedHashSet<Character> ();

        for(char c : s.toCharArray()) {

            System.out.println(unique.add(c));
        }
        for(char dis:unique){
            System.out.println(dis);
        }


    }
}
0
ответ дан Pigueiras 28 August 2018 в 10:36
поделиться

Существует также ImmutableSet из Guava в качестве опции ( здесь - документация):

ImmutableSet.copyOf(list);
21
ответ дан RAnders00 28 August 2018 в 10:36
поделиться
2
ответ дан RAS 28 August 2018 в 10:36
поделиться

Решение @ jonathan-stafford в порядке. Но это не сохраняет порядок списка.

Если вы хотите сохранить порядок в списке, вы должны использовать это:

public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator();    iter.hasNext(); ) {
   Object element = iter.next();
   if (set.add((T) element))
      newList.add((T) element);
   }
   list.clear();
   list.addAll(newList);
}

Это только для завершения ответа. Очень хорошо!

0
ответ дан sharkbait 28 August 2018 в 10:36
поделиться
        List<String> result = new ArrayList<String>();
        Set<String> set = new LinkedHashSet<String>();
        String s = "ravi is a good!boy. But ravi is very nasty fellow.";
        StringTokenizer st = new StringTokenizer(s, " ,. ,!");
        while (st.hasMoreTokens()) {
            result.add(st.nextToken());
        }
         System.out.println(result);
         set.addAll(result);
        result.clear();
        result.addAll(set);
        System.out.println(result);

output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
1
ответ дан siva 28 August 2018 в 10:36
поделиться
    ArrayList<String> list = new ArrayList<String>();
    HashSet<String> unique = new LinkedHashSet<String>();
    HashSet<String> dup = new LinkedHashSet<String>();
    boolean b = false;
    list.add("Hello");
    list.add("Hello");
    list.add("how");
    list.add("are");
    list.add("u");
    list.add("u");

    for(Iterator iterator= list.iterator();iterator.hasNext();)
    {
        String value = (String)iterator.next();
        System.out.println(value);

        if(b==unique.add(value))
            dup.add(value);
        else
            unique.add(value);


    }
    System.out.println(unique);
    System.out.println(dup);
0
ответ дан SparkOn 28 August 2018 в 10:36
поделиться

Если вы хотите удалить дубликаты из ArrayList, найдите следующую логику,

public static Object[] removeDuplicate(Object[] inputArray)
{
    long startTime = System.nanoTime();
    int totalSize = inputArray.length;
    Object[] resultArray = new Object[totalSize];
    int newSize = 0;
    for(int i=0; i<totalSize; i++)
    {
        Object value = inputArray[i];
        if(value == null)
        {
            continue;
        }

        for(int j=i+1; j<totalSize; j++)
        {
            if(value.equals(inputArray[j]))
            {
                inputArray[j] = null;
            }
        }
        resultArray[newSize++] = value;
    }

    long endTime = System.nanoTime()-startTime;
    System.out.println("Total Time-B:"+endTime);
    return resultArray;
}
0
ответ дан Thananjayan N 28 August 2018 в 10:36
поделиться

LinkedHashSet выполнит трюк.

String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
    System.out.println(s1);

System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
     System.out.println(arr3[i].toString());

// output: 5,1,2,3,4

1
ответ дан user1912383 28 August 2018 в 10:36
поделиться

это может решить проблему:

private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {

Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
     cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
10
ответ дан user2868724 28 August 2018 в 10:36
поделиться

Наверное, немного перебор, но мне нравится такая изолированная проблема. :)

Этот код использует временную Set (для проверки уникальности), но удаляет элементы непосредственно в исходном списке. Поскольку удаление элементов внутри ArrayList может вызвать огромное количество копий массивов, метод remove (int) исключается.

public static <T> void removeDuplicates(ArrayList<T> list) {
    int size = list.size();
    int out = 0;
    {
        final Set<T> encountered = new HashSet<T>();
        for (int in = 0; in < size; in++) {
            final T t = list.get(in);
            final boolean first = encountered.add(t);
            if (first) {
                list.set(out++, t);
            }
        }
    }
    while (out < size) {
        list.remove(--size);
    }
}

Пока мы на нем, вот версия для LinkedList (много лучше всего!):

public static <T> void removeDuplicates(LinkedList<T> list) {
    final Set<T> encountered = new HashSet<T>();
    for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
        final T t = iter.next();
        final boolean first = encountered.add(t);
        if (!first) {
            iter.remove();
        }
    }
}

Используйте интерфейс маркера для представления единого решения для List:

public static <T> void removeDuplicates(List<T> list) {
    if (list instanceof RandomAccess) {
        // use first version here
    } else {
        // use other version here
    }
}

EDIT: Я думаю, что generics-stuff действительно не добавляет никаких Здесь. О, хорошо. :)

11
ответ дан volley 28 August 2018 в 10:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: