Reputation: 11
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
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
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
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
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
Reputation: 3580
You could add the elements to the Set collection. If you want to preserve order you should use LinkedHashSet
Upvotes: 2
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