views:

29765

answers:

11

Given an Array of n Objects, let's say is an Array of Strings, and it has the following values:

foo[0]="a";
foo[1]="cc";
foo[2]="a";
foo[3]="dd";

What do I have to do to delete/remove all the Strings/Objects equal to "a" in the Array?
Thanks!

+4  A: 

Make a List out of the array with Arrays.asList(), and call remove() on all the appropriate elements. Then call toArray() on the 'List' to make back into an array again.

Not terribly performant, but if you encapsulate it properly, you can always do something quicker later on.

Dustman
Thank you very much!
ramayac
Re your comment: It's okay, you'll get used to it soon. :-) I posted my post because I didn't want readers to get the idea that elements can be removed from the result of Arrays.asList() (it's an immutable list), so I thought an example could take care of that. :-)
Chris Jester-Young
Uh, I meant un-resizeable list (add() and remove() do not work). :-P It still has a usable set() method. :-)
Chris Jester-Young
Though it may seem strange, my experience is that the performance penalty of this approach is minimal.
Marcus Downing
I'm of the Java 1.4 era, and remember Collections being markedly slower than iterating over arrays. No doubt the introduction of Generics gave Sun ample opportunity to optimize that package.
Dustman
A: 

Assign null to the array locations.

alfinoba
Could you explain?
ramayac
+22  A: 

[If you want some ready-to-use code, please scroll to my "Edit3" (after the cut). The rest is here for posterity.]

To flesh out Dustman's idea:

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

Edit: I'm now using Arrays.asList instead of Collections.singleton: singleton is limited to one entry, whereas the asList approach allows you to add other strings to filter out later: Arrays.asList("a", "b", "c").

Edit2: The above approach retains the same array (so the array is still the same length); the element after the last is set to null. If you want a new array sized exactly as required, use this instead:

array = list.toArray(new String[0]);


Edit3: If you use this code on a frequent basis in the same class, you may wish to consider adding this to your class:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

Then the function becomes:

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

This will then stop littering your heap with useless empty string arrays that would otherwise be newed each time your function is called.

cynicalman's suggestion (see comments) will also help with the heap littering, and for fairness I should mention it:

array = list.toArray(new String[list.size()]);

I prefer my approach, because it may be easier to get the explicit size wrong (e.g., calling size() on the wrong list).

Chris Jester-Young
Excelent, thanks!
ramayac
Glad you liked. I revised my entry to support removing _all_ instances of "a", not just the first. :-)
Chris Jester-Young
Ooff... shot down at the finish line. Knew I should have kept editing. This system takes some getting used to.Good edit!
Dustman
Please consider my post. I think you're code is flawed. Thanks
GHad
GHad: Have you read my Edit2 above? It addresses exactly what you mentioned, and it was posted before your post.
Chris Jester-Young
Why not list.toArray(new String[list.size()]) rather than new String[0], since the code will use the new array if it is the correct size?
cynicalman
Yes, that works. Otherwise, some code (in the Java class library, mainly) store a static instance of String[0] (and other similar zero-sized arrays), and pass the static instances in instead of newing one each time. :-)
Chris Jester-Young
A: 

Something about the make a list of it then remove then back to an array strikes me as wrong. Haven't tested, but I think the following will perform better. Yes I'm probably unduly pre-optimizing.

boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
   if(arr[i].equals("a")){
      deleteItem[i]=true;
   }
   else{
      deleteItem[i]=false;
      size++;
   }
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
   if(!deleteItem[i]){
      newArr[index++]=arr[i];
   }
}
shsteimer
A: 

arrgh can't get code to show up correctly. sorry got it working. sorry again i don't think I read the question properly

String  foo[] = {"a","cc","a","dd"},
       remove = "a";
     boolean gaps[] = new boolean[foo.length];
     int newlength = 0;

     for(int c = 0;c<foo.length;c++)
     {
      if(foo[c].equals(remove))
      {
       gaps[c] = true;
       newlength++;
      }
      else gaps[c] = false;

      System.out.println(foo[c]);
     }

     String newString[] = new String[newlength];

     System.out.println("");

     for(int c1=0,c2=0 ;c1<foo.length;c1++)
     {
      if(!gaps[c1])
      {
       newString[c2] = foo[c1];
       System.out.println(newString[c2]);
       c2++;
      }
     }
AngelOfCake
A: 

EDIT:

The point with the nulls in the array has been cleared. Sorry for my comments. Greetz GHad

Original:

Ehm... the line

array = list.toArray(array);

replaces all gaps in the array where the removed element has been with null. This might be dangerous, because the elements are removed, but the length of the array remains the same!

If you want to avoid this, use a new Array as parameter for toArray(). If you don`t want to use removeAll, a Set would be an alternative:

     String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

     System.out.println(Arrays.toString(array));

     Set<String> asSet = new HashSet<String>(Arrays.asList(array));
     asSet.remove("a");
     array = asSet.toArray(new String[] {});

     System.out.println(Arrays.toString(array));

Gives:

[a, bc, dc, a, ef]
[dc, ef, bc]

Where as the current accepted answer from Chris Yester Young outputs:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

with the code

 String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

 System.out.println(Arrays.toString(array));

 List<String> list = new ArrayList<String>(Arrays.asList(array));
 list.removeAll(Arrays.asList("a"));
 array = list.toArray(array);  

 System.out.println(Arrays.toString(array));

without any null values left behind.

Greetz GHad

GHad
Nice try, but no cigar. I posted an edit on exactly this topic, way before you made your post. So, although you're "technically correct", I don't appreciate your trying to get people to displace my post. I just thought you should know that.
Chris Jester-Young
It's not about post displacement, but about avoiding errors and dangerous code. Greetz GHad
GHad
Errors can be avoided if people read my whole post (including both addenda). If people just cut and paste code without thinking, then they deserve everything they get. Programmers get paid what they do because they exercise their brains...I hope. [continues]
Chris Jester-Young
[continued] Your code is "dangerous" too if people aren't cognisant of the fact that by using a hash, the items become disordered. Of course, _thinking_ programmers realise this, but if you call my code dangerous because people cut and paste without thinking, it's only fair to say the same of yours.
Chris Jester-Young
Sure, you're right about the hash. And as the point is clear by your 2nd edit, I must have overread this. As said, just wanted to avoid an array with null values and duplication. You may change your code based upon your 2nd edit and leave a comment in Edit3 about the array. Didn't want to attack you
GHad
Thanks for that. I've added a whole section on how to prevent heap littering, too, that you may be interested in. See source for java.util.EnumSet for an example of this usage.
Chris Jester-Young
+1  A: 

You can always do:

int i, j;
for (i = j = 0; j < foo.length; ++j)
  if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);
A: 

It depends on what you mean by "remove"? An array is a fixed size construct - you can't change the number of elements in it. So you can either a) create a new, shorter, array without the elements you don't want or b) assign the entries you don't want to something that indicates their 'empty' status; usually null if you are not working with primitives.

In the first case create a List from the array, remove the elements, and create a new array from the list. If performance is important iterate over the array assigning any elements that shouldn't be removed to a list, and then create a new array from the list. In the second case simply go through and assign null to the array entries.

DJClayworth
A: 

Thanks a lot!! very helpful

A: 

i dont know...i have been trying this for a while for my java assignment///but couldnt find any soln/....anybody please post the solution

A: 

Insert new object: This command adds a new object to an array of objects. The added data is stored in a file. The file is a text file that is comma delimited in which each entry (object) is found on a separate line.

I'm not sure this is on topic. The question is about removing an array element, not just nulling it but making it disappear. This answer seems to be about something like the add() method for Arrays, ArrayLists, etc., and visualizing the result by storing the array (or etc.) into a file and dumping the file. Nothing wrong with what's written here, but it doesn't apply in any way to the question.Bill
Bill IV