2

Please, before downvote - read the question and check the example - this is not duplicate!

I want to remove every duplicated element from ArrayList in Java, like this:

Original list: [4, 2, 2, 3, 4, 1]
Set result: [1, 2, 3, 4]
Desired result: [1, 3]

The obvious solution for duplicates - set does not work here.

My solution:

        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(5);
        arrayList.add(1);
        arrayList.add(5);
        arrayList.add(1);
        arrayList.add(5);
        arrayList.add(2);
        arrayList.add(3);

        ArrayList<Integer> temp = new ArrayList<>(arrayList);

        for(Integer number : new HashSet<Integer>(arrayList)){
            temp.remove(number);
        }

        arrayList.removeAll(temp);

Any smarter/more clever solutions?

bartektartanus
  • 15,284
  • 6
  • 74
  • 102
  • 3
    The duplicate provided wasn't correct, but you still haven't shown any effort. – Sotirios Delimanolis Jul 28 '14 at 15:22
  • Duplicate of what? Anyway what is your question and problem you are facing? I can see what you want to achieve but I don't see part which you explain what stops you from doing it. – Pshemo Jul 28 '14 at 15:22
  • I've asked this question 2 min ago and got 6 downvotes for duplicate question, but it's clearly not. – bartektartanus Jul 28 '14 at 15:23
  • The downvote was not for duplicates necessarily. You need to show us what you've tried already. – Swapnil Jul 28 '14 at 15:24
  • You didn't post any code showing what you have tried. On top of that, if a question is downvoted, do not repost it – TFischer Jul 28 '14 at 15:24
  • Have you read: http://stackoverflow.com/questions/2849450/how-to-remove-duplicates-from-a-list http://stackoverflow.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist http://stackoverflow.com/questions/10370750/removing-duplicate-elements-from-a-list http://stackoverflow.com/questions/20433692/java-remove-duplicate-objects-in-arraylist – Al Lelopath Jul 28 '14 at 15:25
  • Homework! Ask your teach or TA for help. – markspace Jul 28 '14 at 15:25
  • 5
    @mickey Your links are not correct. Check "Desired result", not "Set result". – Pshemo Jul 28 '14 at 15:26
  • @Pshemo: I understand what you are saying: None of these links provide code to give the Desired result. As suggested by a couple other responses, it appears that the OP has not tried anything. The code in these links could point the way. – Al Lelopath Jul 28 '14 at 15:29
  • @bartektartanus Is your original list always sorted? – Pshemo Jul 28 '14 at 15:35
  • Nope, it's just an example :) – bartektartanus Jul 28 '14 at 15:37
  • 3
    Since you already have a working solution and you are interested in improving it (I assume it doesn't have bugs) you should post your question on http://codereview.stackexchange.com/. General rule is (1) if your code works but you'd love to hear how it could work better post on Code Review (2) if you are trying to get your code to work post on Stack Overflow. Anyway since you already posted your question on Stack Overflow this advice is for your future questions (you should post question only on one of StackExchange sites so choose either SO or CR, never post same question both sites). – Pshemo Jul 28 '14 at 16:00

3 Answers3

3

There are many ways to do what you are looking to do. Here is one (where T is the type stored by your existing List):

  1. Allocate a Map<T, Integer>. The integer will be used to store the number of times that item appears in your list.
  2. Iterate over your list. Look up each item in the map. If it doesn't exist, put back a count of one. If it does already exist in the map, increment the count and put back the new count.
  3. Iterate over the Entry's in the map to extract your de-duplicated list. You will not include any Entry with a value that is greater than one.

This approach will be fast even for large lists.

Rob
  • 6,247
  • 2
  • 25
  • 33
2

Alternatively you can check for frequency as remove as well. Collections.frequency(arrayList, number)

public static void main(String[] args) {
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    arrayList.add(5);
    arrayList.add(1);
    arrayList.add(5);
    arrayList.add(1);
    arrayList.add(5);
    arrayList.add(2);
    arrayList.add(3);

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

    for (Integer number : arrayList) {
        if (Collections.frequency(arrayList, number) == 1) {
            unique.add(number);
        }
    }

    System.out.println(unique);
}
JamesB
  • 7,774
  • 2
  • 22
  • 21
Syam S
  • 8,421
  • 1
  • 26
  • 36
  • 4
    You could also change the frequency condition to == 1 and then use the resultant list as the list of those numbers not repeated. – JamesB Jul 28 '14 at 15:47
  • Yes. Good idea. That will void an additional looping. Updated my answer.. :) – Syam S Jul 28 '14 at 15:50
1

You can use a loop to check for duplicates in an ArrayList, and then use remove() on the ArrayList to remove the elements.

Please see the following:

{
    ArrayList list;
    // ...
    while(true)
        for(final Integer o : list) {
            if(list.indexOf(o) != list.lastIndexOf(o)) {
                while(list.remove(o));
                continue;
            }
            break;
        }
}

Alternatively a better approach would be to use a temporary Set to store the objects to remove:

{
    ArrayList list;
    TreeSet<Integer> set = new TreeSet<>(); // Use your Set!
    // ...
    for(final Integer o : list)
        if(list.indexOf(o) != list.lastIndexOf(o))
            set.add(o);
    for(final Integer o : set)
        while(list.remove(o));
}
Community
  • 1
  • 1
Unihedron
  • 10,902
  • 13
  • 62
  • 72
  • I think it's better to simply copy the list - iterate over one and remove from another :) – bartektartanus Jul 28 '14 at 15:39
  • 3
    You shouldn't modify collection which you are iterating with for-each loop. – Pshemo Jul 28 '14 at 15:40
  • @Pshemo I've fixed it. Please note that `Iterable` used in `for`-each loops concurrently calls `.next()` until `.hasNext()` returns false, therefore you need to restart the iteration after each modification (`continue` -> redo `while(true)` block -> `for`-each again). – Unihedron Jul 28 '14 at 15:42
  • FYI, added solution for use of a temporary `Set`. – Unihedron Jul 28 '14 at 15:45