3

I wanted to remove duplicates from an array, by using an array list. The code seems to work fine for all cases except when String[]array contains three copies of an element. Why does this problem happen and how to fix it ?

Test input - 
array = {"D22", "D22", "D22"};

Output = 
D22
D22

Expected output = 
D22

public static String[] removeDuplicates(String [] array){
    String [] noDups = null;
    ArrayList<String> copy = new ArrayList<String>();
    String first = "";
    String next = "";

    for(String s: array){
        copy.add(s.trim());//Trimming
    }

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

        for(int j = i + 1; j < copy.size(); j++){

            first = copy.get(i);
            next = copy.get(j);

            if(first.equals(next)){
                copy.remove(j);
            }

        }


    }

    noDups = copy.toArray(new String[copy.size()]);

    for(String s: noDups){
        System.out.println(s);

    }

    return noDups;
}
1
  • 1
    I know that could use a set instead. Btw, i prefer to use an arraylist for now. Commented Nov 25, 2013 at 5:37

4 Answers 4

4

Try this, it is most simpler:

public static String[] removeDuplicates(String[] array) {
    ArrayList<String> res = new ArrayList<String>();

    for (String str : array) {
        if (!res.contains(str)) {
            res.add(str);
        }
    }
    return res.toArray(new String[res.size()]);
}

public static void main(String[] args) {
    String[] arr = {"D22", "D22", "D22"};
    String[] res = removeDuplicates(arr);
    for (String string : res) {
        System.out.println(string);
    }
}

Output: D22

Sign up to request clarification or add additional context in comments.

3 Comments

This is also much safer though as an answer could do with an explanation of the OP's problem.
@Trojan.ZBOT, How you print your value. I have posted full code with output. Now try again. No reason to print duplicate value.
@Masud - Thanks. My mistake. I kept the code separately and it worked. Must be some error in the other code which I added.
2

It is because when you call remove, your counter is also incrementented, resulting in it skipping over an element. Something like

if(first.equals(next)){
  copy.remove(j);
  j--;
}

should fix this

3 Comments

A slightly simpler option is to have your loops count backwards.
This is why you aren't supposed to modify a list while looping over it. The while(Iterator#hasNext()) idiom is intended for this.
@Trojan.ZBOT Yes because your loop goes from 0 to list.size() and the control variable is used as an array index. It's bad because you modify the size and indexes while you are looping. There is actually an exception (ConcurrentModificationException) specifically about this. Pulling the list's Iterator and looping over that (typically with the above while condition) is safer because the iterator will take the removals in to account.
1

When you remove an element from an array, each following element moves one space to the left. This causes you to effectively skip an element. Demonstration:

Initial state
Index:   0 1 2
Element: A B C
i: 0
j: 1
A=B, therefore A is removed
Index:   0 1
Element: B C
j: 2 (You increment it regardless of whether an element was removed)
j>=size(), therefore go to outer loop
i: 1
There is nothing after element C, therefore you're done.

Comments

0

If you look at the for loop closely for(int j = i + 1; j < copy.size(); j++){ the value of copy.size() gets computed every time you iterate over the list. As you are removing the values from the copy list the size is diminished by one.

You are iterating as well as modifying the same list (by using copy.remove(j);) which is causing the issue.

Couple of alternatives to this:

  • Use Set instead of List. It will automatically remove duplicates.
  • Or when your are iterating over the copy list, add non-duplicate value to some other list list instead of modifying the copy list.

2 Comments

I don't want to use a set for now.
You can go with the second approach in that case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.