1

Is their a prebuilt method that works differently than removeAll to remove all of a certain value in an array list?

I have a method to delete duplicates in arrayLists that looks like this:

The first 2 for for loops work and set it correctly but I don't know what to do for the second for loop to delete all values of -1 from the ArrayList or is their a better way to do this?

public static ArrayList<Integer> deleteDuplicates(ArrayList<Integer> a) {    
    for (int i = 0; i < a.size(); i++) {
      for (int j = (i + 1); j < a.size(); j++) { 
        if (a.get(i) == a.get(j) && i != j) {
          a.set(j, -1); 
        }
      }
    }
    for (int i = 0; i < a.size(); i++) {
      if (a.get(i) == -1) {
        a.removeAll(int -1);
      }
    }

The removeAll(int -1) thing at the bottom doesn't compile, I just left it there so you can see what I'm trying to do.

EDIT:

replaced the for loop at the bottom with this:

  for (int i = 0; i < a.size(); i++) {
      if (a.get(i) == -1) {
        a.remove(i);
        i--;
      }
    }

pretty sure that works.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
Rose
  • 11
  • 3
  • Please explain this line `if (a.get(i) == -1)` – DCruz22 Mar 17 '16 at 00:55
  • If you want to avoid duplicates have you considered using a set/hashset? – Matthew Wright Mar 17 '16 at 00:57
  • a.remove(i); Since you are using for loop to check every element one by one there is no need to use removeall, just use a.remove(i); There is a better way to remove the duplicates by putting them into a set, set cannot contain duplicated value so it removes the duplicate automatically. Hope it helps. – Arsaceus Mar 17 '16 at 00:58
  • 2
    Be _very_ careful with `List` - there is `remove(int)` which removes the item at a specified index, and `remove(Integer)` which removes the object specified. Due to autoboxing conventions, it can be _very_ easy to call the wrong method, often resulting in a lot of frustrating debugging. – Krease Mar 17 '16 at 00:58
  • 1
    `removeAll(Collections.singleton(-1))` might be what you're looking for. – Louis Wasserman Mar 17 '16 at 00:59

2 Answers2

1

A possibly less efficient, but far more readable way of accomplishing this is to use a Set to filter the duplicates:

public static ArrayList<Integer> deleteDuplicates(ArrayList<Integer> a) {
   return new ArrayList<Integer>(new TreeSet<Integer>(a));
}

For most cases, like very large Lists, this will be a better option.

Given the option, avoid the need to convert an ArrayList all together by declaring your initial ArrayList<Integer> as a Set<Integer>. If so, this method would be come unnecessary.

pczeus
  • 7,709
  • 4
  • 36
  • 51
  • I tried the TreeSet thing and I get the error message: .java:22: error: illegal start of expression ArrayList b = ArrayList<>(new TreeSet(a)); ^ 1 error – Rose Mar 17 '16 at 01:14
  • I updated the code in the answer to help correct your issue. – pczeus Mar 17 '16 at 01:17
  • this is declaring a set so I have the line of code: ArrayList b = ArrayList(new TreeSet(a)); and then I have a really basic for loop that deletes the duplicates after its sorted but the first line gives me the error message: Generate.java:90: error: cannot find symbol ArrayList b = ArrayList(new TreeSet(a)); ^ symbol: variable ArrayList location: class Generate – Rose Mar 17 '16 at 01:21
  • and these: Generate.java:90: error: cannot find symbol ArrayList b = ArrayList(new TreeSet(a)); ^ symbol: variable Integer location: class Generate Generate.java:90: error: cannot find symbol ArrayList b = ArrayList(new TreeSet(a)); ^ symbol: class TreeSet location: class Generate 3 errors – Rose Mar 17 '16 at 01:22
  • you need to have an import statement for both ArrayList and TreeSet, both can be imported with the statement at the top of your class: `import java.util.*;` – pczeus Mar 17 '16 at 01:33
  • A `LinkedHashSet` would be better, since it will retain the original order of the values. It may even perform better. Since the input is a `List`, order may be important. – Andreas Mar 17 '16 at 01:41
0

As others have pointed out, the most elegant way would be to use a Set; which takes care of duplicate values automatically.

I would even go one step further: if you have control over the input data ... then do not use an ArrayList at all. It is simply a waste of memory and CPU cycles to first fill a list with values; to then transform it into a Set to eliminate duplicates; to then turn that into a list again. You are constantly creating new objects without the need to.

Instead: use a set right from the beginning. So, if possible change the code that "receives" the input data to directly store within a set.

( side note: the different collection classes like HashSet, ArrayList, ... have different "cost" for different kinds of operations. In that sense you might want to check this question to determine which collection type best fits your needs )

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248