How do I remove objects from an array in Java?
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 new
ed 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);
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, 2021Comments
-
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 almost 16 yearsGlad you liked. I revised my entry to support removing all instances of "a", not just the first. :-)
-
Dustman almost 16 yearsOoff... shot down at the finish line. Knew I should have kept editing. This system takes some getting used to. Good edit!
-
C. K. Young almost 16 yearsRe 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 almost 16 yearsUh, I meant un-resizeable list (add() and remove() do not work). :-P It still has a usable set() method. :-)
-
Marcus Downing almost 16 yearsThough it may seem strange, my experience is that the performance penalty of this approach is minimal.
-
Dustman almost 16 yearsI'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 almost 16 yearsGHad: Have you read my Edit2 above? It addresses exactly what you mentioned, and it was posted before your post.
-
C. K. Young almost 16 yearsNice 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 almost 16 yearsIt's not about post displacement, but about avoiding errors and dangerous code. Greetz GHad
-
C. K. Young almost 16 yearsErrors 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 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 almost 16 yearsWhy 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 almost 16 yearsYes, 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 almost 16 yearsThanks 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 over 12 yearsWhat's with this? @Chris pointed out that the list resulting from
Arrays.asList()
doesn't supportremove()
. So is this answer completely invalid? Looks like maybe some comments got removed, so I don't know if this was discussed. -
DDSports almost 11 yearsI 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 over 9 yearshi, 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 over 8 yearsThis 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 over 8 yearsThis 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 about 8 yearsBoth 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 about 7 yearsPlease 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 about 7 yearsAlthough neat, this is going to be amazingly inefficient compared to System.arraycopy. Probably shouldn't do this in real code.
-
Bill K about 7 yearsThis 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 about 7 yearsthank 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 almost 6 yearsif 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 over 5 years
ArrayUtils.removeElement(boolean[] array, boolean element)
is also very useful. -
S_K about 5 yearsFor 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 about 4 yearsThe question states "Given an array of n Objects" — so
Stream.of(foo).filter(s -> ! s.equals("a")).toArray()
would be sufficient. -
Kaplan over 3 yearsMore often I only want to remove the first of several equal entries.