简体   繁体   中英

Unique Integers From Array List

I am having problems with making a method that will return distinct integers of the array list. I really want to do it with removing the duplicates and then just display the array list. I cannot figure out what is the problem. When I test it out this is the output I get: [3, 11, 33, 10]

This is my code

package getUniques;

import java.util.ArrayList;

public class Uniques {

    public static ArrayList<Integer> getUniques( ArrayList<Integer> list ){
        int i = 0;
        while(i < list.size() - 1){

            for (int j = 0; j < list.size(); j++){

                if (list.get(i) == list.get(j))
                    list.remove(i);
            }
            i++;
        }

        return list;
    }

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(3);
        list.add(5);
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(22);
        list.add(10);
        System.out.println(getUniques(list));
    }

}

You can also get unique values by using Set . Insert the values in a Set and then put it back into an ArrayList like new ArrayList(theSet);

Changing the list as you iterate over it is always going to cause pain! Say you remove item 3 (so the old 4th becomes the new 3) - then you do i++, so you are effectively skipping the "old 4th" element.

You can skip the i++ if you removed the item to get back on track, but a some other solutions:

  1. Use a Set or similar in the first place so you can't get duplicates.

  2. Use a second list to hold the values (or indexes) of items you want to remove (if using indexes, you can remove them highest to lowest else you end up with the same issue: delete index 1, index 4 is now index 3...)

  3. Flip your search so you are going back towards 0, same principal applies. You can remove high indexes without impacting lower ones.

  4. Make your outer loop use an iterator so you can use the remove operation.

To remove items while iterating, you have to use an iterator, as it guarantees the order:

Iterator<Integer> iterator = list.iterator();
int i = 0;
List<Integer> listCopy = new ArrayList<Integer>(list);
while(iterator.hasNext()){
    i++;
    Integer value = iterator.next()
    for (int j = i; j < listCopy.size(); j++){
        if (value.equals(listCopy.get(j))) {
            iterator.remove();
        }
    }
}

However, in this case, as you need to iterate twice through the same list, it's not the best solution. It might be faster putting everything into a sorted Set, as Set removes duplicates on its own.

Your code has a few problems. Here's fixes for your existing code:

First you are removing the wrong index. You've identified the element at j as the duplicate; remove it instead of the element at i .

list.remove(j);  // j not i

Next, you are removing all elements that are the same, and you aren't leaving the "original". To fix this, only test (and remove) those that are past i in the loop.

for (int j = i + 1; j < list.size(); j++){  // Start at i + 1, not 0.

Then you'll need to retry your j index once you've removed it, because the rest of the elements have been shifted backwards 1 spot. Instead of

if (list.get(i) == list.get(j))
    list.remove(i);

Try

if (list.get(i) == list.get(j))
{
    list.remove(j);
    j--;  // Try this j again next loop, once it's incremented again.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM