it-roy-ru.com

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

У меня есть ArrayList<String>, и я хочу удалить из него повторяющиеся строки. Как я могу это сделать?

444
user25778

Если вам не нужны дубликаты в Collection, вам следует подумать, почему вы используете Collection, который разрешает дублирование. Самый простой способ удалить повторяющиеся элементы - это добавить содержимое в Set (который не допускает дублирования), а затем добавить Set обратно в ArrayList:

Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);

Конечно, это разрушает порядок элементов в ArrayList.

920
jonathan-stafford

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

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

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

281
abahgat

В Java 8:

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

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

112
Vitalii Fedorenko

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

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

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

52
Benno Richters

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

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

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

До Java 8

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

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

Использование гуавы

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

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

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

Примечание: В случае, если мы хотим получить результат в конкретной реализации списка, например. LinkedList тогда мы можем изменить приведенный выше пример как:

List<String> deDupStringList3 = strList.stream().distinct()
                 .collect(Collectors.toCollection(LinkedList::new));

Мы также можем использовать parallelStream в приведенном выше коде, но это может не дать ожидаемых преимуществ в производительности. Проверьте это вопрос для более.

44
i_am_zero

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

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 в соответствии с тем, что вы хотите отстаивать для равенства)

27
stbn

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

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
26
Nenad Bulatovic

Потоки 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());

Как удалить дубликаты элементов из массива

23
infoj

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

ImmutableSet.copyOf(list);
22
Timofey Gorshkov

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

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

    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

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

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;
}
12
user2868724

Возможно, это немного излишне, но мне нравится такая отдельная проблема. :)

Этот код использует временный набор (для проверки уникальности), но удаляет элементы непосредственно внутри исходного списка. Поскольку удаление элемента внутри ArrayList может вызвать огромное количество копирования массива, метод удаления (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
    }
}

Правка: я думаю, что дженерики действительно не добавляет никакой ценности здесь ... Ну, хорошо. :)

12
volley
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

Если вы хотите использовать стороннюю библиотеку, вы можете использовать метод 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() сохраняет порядок исходного списка, сохраняя первое вхождение каждого элемента. Это реализовано с использованием как Set, так и List.

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
Craig P. Motlin

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

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

Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
3
M Kaweepatt Churcharoen
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

Код:

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
sambhu

Если вы используете модель типа List <T>/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--;
                            }
                        }
                    }
2
Saurabh Gaddelpalliwar

Когда вы заполняете 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
HarpyWar

Если вы хотите сохранить ваш ордер, то лучше всего использовать LinkedHashSet . Потому что, если вы хотите передать этот список в запрос на вставку путем его итерации, порядок будет сохранен.

Попробуй это

LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);

Это преобразование будет очень полезно, когда вы хотите вернуть список, но не набор.

2
ramakrishnan

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());

// вывод: 5,1,2,3,4

1
user1912383
        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

Это используется для вашего списка пользовательских объектов 

   public List<Contact> removeDuplicates(List<Contact> list) {
    // Set set1 = new LinkedHashSet(list);
    Set set = new TreeSet(new Comparator() {

        @Override
        public int compare(Object o1, Object o2) {
            if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
                    ((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);

    final List newList = new ArrayList(set);
    return newList;
}
1
Gujjula Ramesh Reddy

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

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

Как сказано выше, вы должны использовать класс, реализующий интерфейс Set вместо List, чтобы быть уверенным в уникальности элементов. Если вам нужно сохранить порядок элементов, можно использовать интерфейс SortedSet; класс TreeSet реализует этот интерфейс.

1
Vinze
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
reddy
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

Сложность времени: O(n): без набора

private static void removeDup(ArrayList<String> listWithDuplicateElements) {
    System.out.println(" Original Duplicate List :" + listWithDuplicateElements);
    List<String> listWithoutDuplicateElements = new ArrayList<>(listWithDuplicateElements.size());

    listWithDuplicateElements.stream().forEach(str -> {
        if (listWithoutDuplicateElements.indexOf(str) == -1) {
            listWithoutDuplicateElements.add(str);
        }
    });     

    System.out.println(" Without Duplicate List :" + listWithoutDuplicateElements);
}
0
Sameer Shrestha
Set<String> strSet = strList.stream().collect(Collectors.toSet());

Это самый простой способ удалить ваши дубликаты.

0
saif ali

Это правильный вариант (если вы беспокоитесь о накладных расходах HashSet.

 public static ArrayList<String> removeDuplicates (ArrayList<String> arrayList){
    if (arrayList.isEmpty()) return null;  //return what makes sense for your app
    Collections.sort(arrayList, String.CASE_INSENSITIVE_ORDER);
    //remove duplicates
    ArrayList <String> arrayList_mod = new ArrayList<>();
    arrayList_mod.add(arrayList.get(0));
    for (int i=1; i<arrayList.size(); i++){
        if (!arrayList.get(i).equals(arrayList.get(i-1))) arrayList_mod.add(arrayList.get(i));
    }
    return arrayList_mod;
}
0
seekingStillness

Будет ли что-то подобное лучше работать? 

public static void removeDuplicates(ArrayList<String> list) {
Arraylist<Object> ar     = new Arraylist<Object>();
Arraylist<Object> tempAR = new Arraylist<Object>();
while (list.size()>0){
    ar.add(list(0));
    list.removeall(Collections.singleton(list(0)));
}
list.addAll(ar);

}

Это должно поддерживать порядок, а также не быть квадратичным во время выполнения.

0
Ravi Vital
public Set<Object> findDuplicates(List<Object> list) {
        Set<Object> items = new HashSet<Object>();
        Set<Object> duplicates = new HashSet<Object>();
        for (Object item : list) {
            if (items.contains(item)) {
                duplicates.add(item);
                } else { 
                    items.add(item);
                    } 
            } 
        return duplicates;
        }
0
Harsha

Если вы хотите, чтобы ваш список автоматически игнорировал дубликаты и сохранял их порядок, вы можете создать HashList (встроенный список HashMap).

public static class HashList<T> extends ArrayList<T>{
        private HashMap <T,T> hashMap;
        public HashList(){
            hashMap=new HashMap<>();
        }

        @Override
        public boolean add(T t){
            if(hashMap.get(t)==null){
                hashMap.put(t,t);
                return super.add(t);
            }else return false;
        }

        @Override
        public boolean addAll(Collection<? extends T> c){
            HashList<T> addup=(HashList<T>)c;
            for(int i=0;i<addup.size();i++){
                add(addup.get(i));
            }return true;
        }

    }

Usage Example:

HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);
0
LiNKeR

Если вы хотите удалить дубликаты из 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
    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

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

public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {

    ArrayList <T> uniqueArrayList = new ArrayList<T>();
    for (int i = 0; i < myList.size(); i++){
        if (!uniqueArrayList.contains(myList.get(i))){
            uniqueArrayList.add(myList.get(i));
        }
    }

    return uniqueArrayList;
}
0
neo7

Решение @ 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