user3254957
user3254957

Reputation: 11

Deleting duplicate elements in an ArrayList Java

Hi and thanks for reading! I'm currently studying Generics in Java and this is what I'm trying to accomplish:

I need to delete duplicate elements from an ArrayList. Currently, the ArrayList contains integers. I want to first print the original list, and then print the resulting list after removing the duplicates. This is what I have so far. Any help is appreciated!

public static void main(String[] args) {
    ArrayList<Integer> list1 = new ArrayList<Integer>();

    list1.add(1);
    list1.add(1);
    list1.add(1);

    list1.add(2);
    list1.add(2);
    list1.add(2);

    list1.add(3);
    list1.add(3);
    list1.add(3);

    removeDuplicates(list1);

      System.out.println("Original List with Duplicates: \n" + list1);
        System.out.println();
        //System.out.println("After removing duplicates: \n" + list2);

}

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){


    for(int i = 0; i < list2.size(); i++){

    //logic to remove duplicates    


    }

    return list2;
}   

Upvotes: 1

Views: 3629

Answers (6)

Ted Hopp
Ted Hopp

Reputation: 234817

All the other answers so far create a new list. If you want to modify the list in place, you can iterate through the list while using an auxiliary Set to keep track of all elements already seen. The following works for any List (not just ArrayList) that allows elements to be removed:

public static <E> List<E> removeDuplicates(List<E> list){
    ListIterator<E> iter = list.listIterator();
    Set<E> seen = new HashSet<>();
    while (iter.hasNext()) {
        if (!seen.add(iter.next())) {
            // element not added--must have already been seen, so remove element
            iter.remove();
        }
    }
    return list;
}

An alternative is to dump the entire list into a Set, clear the list, and then add all the element of the set back into the list. Depending on the Set implementation, this may or may not preserve order.

public static <E> List<E> removeDuplicates(List<E> list){
    Set<E> unique = new LinkedHashSet<>(list);
    list.clear();
    list.addAll(unique);
    return list;
}

EDIT: If (as per your comment) you wish to completely remove elements that are not unique to start with, you can modify the first approach:

public static <E> List<E> removeNonUnique(List<E> list){
    Set<E> seen = new HashSet<>(); // all values seen
    Set<E> dups = new HashSet<>(); // all values seen more than once
    for (E elt : list) {
        if (!seen.add(elt)) {
            // element not added--must have already been seen, so add to dups
            dups.add(elt);
        }
    }
    // clean out the list
    list.removeAll(dups);
    return list;
}

Note that since we're not modifying the list during the loop, we don't need to have an explicit iterator.

Upvotes: 0

claj
claj

Reputation: 5402

Convert the ArrayList to Set, maybe HashSet and then back to an ArrayList that you could sort if you want the numbers in order (the ordering in Sets are not usually not guaranteed).

HashSet hs<Integer> = new HashSet(list1);

ArrayList<Integer> uniqueList = Collections.sort(new ArrayList<Integer>(hs));

There's also various SortedSet, among them TreeSet.

Also, you can use a less error-prone for loop construction:

for (int i : uniqueList) {
   System.out.println(i);
}

Upvotes: 0

Yuriy Chulovskyy
Yuriy Chulovskyy

Reputation: 163

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){
    LinkedHashSet<E> dataSet = new LinkedHashSet<E>(list2.size());
    dataSet.addAll(list2);
    ArrayList<E> uniqueLists = new ArrayList<E>(dataSet.size());
    uniqueLists.addAll(dataSet);
    return uniqueLists;
}

Upvotes: 0

Hugo Sousa
Hugo Sousa

Reputation: 1926

public static void main(String[] args) {
    ArrayList<Integer> list1 = new ArrayList<Integer>();
    ArrayList<Integer> list2 = new ArrayList<Integer>();

    list1.add(1);
    list1.add(1);
    list1.add(1);

    list1.add(2);
    list1.add(2);
    list1.add(2);

    list1.add(3);
    list1.add(3);
    list1.add(3);



      System.out.println("Original List with Duplicates: \n" + list1);
      System.out.println();

      list2 = removeDuplicates(list1);

      System.out.println("After removing duplicates: \n" + list2);

}

public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){

    ArrayList<E> usedList = new ArrayList<E>();
    ArrayList<E> newList = new ArrayList<E>();

    for(int i = 0; i < list2.size(); i++){

        E object = list2.get(i);

        if(! usedList.contains(object))
        {
            usedList.add(object);
            newList.add(object);
        }
    }

    return newList;
} 

Output (as expected):

Original List with Duplicates: 
[1, 1, 1, 2, 2, 2, 3, 3, 3]

After removing duplicates: 
[1, 2, 3]

If you're working with other types (not java standard like int), then you have to override the equals method, because it's used in the ArrayList contains method.

Upvotes: 0

jonasnas
jonasnas

Reputation: 3580

You could add the elements to the Set collection. If you want to preserve order you should use LinkedHashSet

Upvotes: 2

Rainbolt
Rainbolt

Reputation: 3660

Step One

Convert your list to a set.

Set<Integer> aSet = new HashSet<Integer>(list);

Step Two

Convert your set back to a list.

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

Why it Works

Sets can only contain unique elements.

Upvotes: 1

Related Questions