How do I remove objects from an array in Java?

373,804

Solution 1

[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<>();
Collections.addAll(list, 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).

Solution 2

An alternative in Java 8:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);

Solution 3

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.

Solution 4

You can use external library:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

It is in project Apache Commons Lang http://commons.apache.org/lang/

Solution 5

See code below

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);
Share:
373,804
IrishGuy
Author by

IrishGuy

Professional software developer, interested in all aspects of consumer internet and enterprise software. Experience developing solutions for: retail, advertising, finance and telco industries. Specialties: Software design and development. Planning and task execution, pushing software projects to "go live". Strong experience using: TDD, Scrum, SEO Tools and Analytics. Interested in marketing and brand development, management, coaching, leadership, payment solutions and financial services. Preferred Languages: Java, PHP, Python, Node DB: DB2, Sybase, MySQL, SQLite3 BPM: Pega 7.x

Updated on February 24, 2021

Comments

  • IrishGuy
    IrishGuy over 3 years

    Given an array of n Objects, let's say it 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?

  • C. K. Young
    C. K. Young almost 16 years
    Glad you liked. I revised my entry to support removing all instances of "a", not just the first. :-)
  • Dustman
    Dustman almost 16 years
    Ooff... shot down at the finish line. Knew I should have kept editing. This system takes some getting used to. Good edit!
  • C. K. Young
    C. K. Young almost 16 years
    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. :-)
  • C. K. Young
    C. K. Young almost 16 years
    Uh, I meant un-resizeable list (add() and remove() do not work). :-P It still has a usable set() method. :-)
  • Marcus Downing
    Marcus Downing almost 16 years
    Though it may seem strange, my experience is that the performance penalty of this approach is minimal.
  • Dustman
    Dustman almost 16 years
    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.
  • C. K. Young
    C. K. Young almost 16 years
    GHad: Have you read my Edit2 above? It addresses exactly what you mentioned, and it was posted before your post.
  • C. K. Young
    C. K. Young almost 16 years
    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.
  • GHad
    GHad almost 16 years
    It's not about post displacement, but about avoiding errors and dangerous code. Greetz GHad
  • C. K. Young
    C. K. Young almost 16 years
    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]
  • C. K. Young
    C. K. Young almost 16 years
    [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.
  • cynicalman
    cynicalman almost 16 years
    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?
  • C. K. Young
    C. K. Young almost 16 years
    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. :-)
  • C. K. Young
    C. K. Young almost 16 years
    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.
  • LarsH
    LarsH over 12 years
    What's with this? @Chris pointed out that the list resulting from Arrays.asList() doesn't support remove(). So is this answer completely invalid? Looks like maybe some comments got removed, so I don't know if this was discussed.
  • DDSports
    DDSports almost 11 years
    I felt the need to post this, as I often use snippets of code which don't work because I missed something that other coders take for granted. GHad made the point about Array size that got my code working (thanks for making that clear). Trying stuff out is the way to learn, and if that means I deserve all I get for taking code from SO and trying to understand how/why it works, then so be it. As an unpaid amateur, I'm not the Java genius that some like to think they are! Thankfully, most of the SO contributors answer questions to help others write better code: For that, you deserve thanks!
  • Nikhitha Reddy
    Nikhitha Reddy over 9 years
    hi, I am using array.remove function. I want to remove 40320 elements from array and it will be done 9 times in my program execution . It's taking so much time. Is there any efficient method to do that.
  • Jason
    Jason over 8 years
    This answer is confusing as it has a number of answers to the question and not all of them actually answer the question. Please remove all but the correct answer.
  • Jason
    Jason over 8 years
    This should be the accepted answer. Although not pretty considering other programming languages can do this with less and clearer code... this is the best Java has to offer without depending on another library.
  • Igor Soudakevitch
    Igor Soudakevitch about 8 years
    Both Chris and LarsH are right: array-backed Lists (in other words, those that get created with Arrays.asList()) are structurally immutable which totally invalidates this answer. Yet, as of now, I see seventeen upvotes. Makes one wonder...
  • Bill K
    Bill K about 7 years
    Please don't do this. It's confusing, slow and error-prone. Just use System.arraycopy() instead--although bonus points for the fact that if you are going to manipulate an array this way you must track length.
  • Bill K
    Bill K about 7 years
    Although neat, this is going to be amazingly inefficient compared to System.arraycopy. Probably shouldn't do this in real code.
  • Bill K
    Bill K about 7 years
    This is a really good answer although your great test code makes it look a lot bigger than it actually is. The entire solution could be a single line arraycopy (assuming you use the same array which is what you'd want to do if you were working so close to the metal you were using arrays instead of collections).
  • Andre
    Andre about 7 years
    thank you, i wrote it so readers can see a bit what goes on under the hood and test it, now i look at it again System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length) ; can be removed and replaced by something like for(i = 0; i < (arr.length - t); i++){ tmp2[i] = tmp1[i]; } you can also create a byte buffer and copy 8 bytes at a time on a 64bit machine to gain extra copy performance
  • Mahender Reddy Yasa
    Mahender Reddy Yasa almost 6 years
    if foo is dynamic string variable it's throwing compile time error Local variable foo defined in an enclosing scope must be final or effectively final
  • scai
    scai over 5 years
    ArrayUtils.removeElement(boolean[] array, boolean element) is also very useful.
  • S_K
    S_K about 5 years
    For me, The problem is I am trying to convert the list of object array comes from the hibernate native query result to dto directly. And, I solved it using setting values manually from an object array.
  • Kaplan
    Kaplan about 4 years
    The question states "Given an array of n Objects" — so Stream.of(foo).filter(s -> ! s.equals("a")).toArray() would be sufficient.
  • Kaplan
    Kaplan over 3 years
    More often I only want to remove the first of several equal entries.