I am trying to remove an object from an ArrayList, My code is
ArrayList myArrayList=new ArrayList();
for(int index=0;index<20;index++){
myArrayList.add(index);
}
for(int removeIndex=0;removeIndex<=mArrayList;removeIndex++){
myArrayList.remove(removeIndex);
}
It is giving a java.lang.IndexOutOfBoundsException. How do I remove a number of objects from ArrayList?.
Of course, as soon as you remove the 0th item, the last item is now 18th, because the items are reindexed.
You can use several tricks, for example, remove starting from the end. Or remove the 0th item until the array is empty (or until you removed some predefined number of items).
Code:
for(int index = mArrayList.size() - 1; removeIndex >= 0; removeIndex--) {
myArrayList.remove(removeIndex);
}
or
for(int nremoved = mArrayList.size() - 1; nremoved >= 0; nremoved--) {
myArrayList.remove(0);
}
If you want to remove all the items, you can consider using clear() as well.
If you want to remove several positions from a list, you can try the following:
Collections.sort(positions); // needed if not already sorted
for (int i = positions.size() - 1; i >= 0; i--)
myArrayList.remove(positions.get(i));
List#clear() will remove all elements.
You have to check '<' while removing.
ArrayList myArrayList = new ArrayList();
for(int index=0;index<20;index++){
myArrayList.add(index);
}
for(int removeIndex=0;removeIndex<myArrayList.size();removeIndex++){
myArrayList.remove(removeIndex);
}
When you remove an element from ArrayList all its subsequent elements reduce their indeces by one.
Please refer to
public ArrayList.remove(int index)
if you needed to remove all elements from Array, and if is possible, then better would be
myArrayList = new ArrayList();
and inside loop you have to reset Array this way, because clear() or removeAll() doesn't works
You're comparing your removeIndex to the ArrayList itself instead of to ArrayList.size(). Also, you should use smaller than ( < ) instead of smaller than or equal to ( <= ) in the comparison, because using < results in an extra loop which causes an indexOutOfBoundsException.
Furthermore, start removing at the end of the ArrayList instead of at the beginning to avoid re-indexing of the elements, which can also cause an indexOutOfBoundsException. (Not in this case since you're comparing to Array.size() every loop. Instead you're removing every second item, as Vlad also mentions.)
In most common way use Iterator instead:
final Iterator<? extends T> it = collection.iterator();
while ( it.hasNext() ) {
T t = it.next();
if (isNeedToRemove(t)) {
it.remove();
}
}
Related
i know how to iterate the last n element of a list using :
for(int i = list.size()-1; i>elements ; i --)
{
list.element.get(i).makeSomeStuff();
list.remove(list.element.get(i));
}
but i need to remove the elements from the list safely without messing around with the index
The idea is to create a secondary list to hold the objects that you want to delete from the originating list.
List<MyObject> toBeRemovedList = new ArrayList()<>;
for(int i = list.size()-1; i>elements ; i --)
{
MyObject myObject = list.get(i);
myObject.makeSomeStuff(); //perform object action
toBeRemovedList.add(myObject); //add the object into the removal list
}
list.removeAll(toBeRemovedList); //remove all the elements of the removal list from the originating list, no index interfering
Use an Iterator instead of an indexed for loop if you need to remove elements from the collection (List in your case). See Remove entries from the list using iterator
Consider a linked list of strings I got from somewhere
LinkedList<String> names = getNames();
Now, I want to remove the first k elements from the list. Currently, I'll do it this way:
for (int i = 0 ; i < k ; i++) {
names.removeFirst();
}
Is there some way to do it more efficiently and to instead call something like:
names.removeRange(0, k);
Note that I prefer not to construct a whole new list using sublist(), as for small k values, popping k times would be even more efficient than constructing the new list
Maybe Something like this :
names.subList(0, k).clear();
this is more efficient but doesn't release memory according to sublist it's just a view:
names.sublist(k, names.size());
I am looping through a list A to find X. Then, if X has been found, it is stored into list B. After this, I want to delete X from list A. As speed is an important issue for my application, I want to delete X from A without looping through A. This should be possible as I already know the location of X in A (I found its position in the first line). How can I do this?
for(int i = 0; i<n; i++) {
Object X = methodToGetObjectXFromA();
B.add(X);
A.remove(X); // But this part is time consuming, as I unnecessarily loop through A
}
Thanks!
Instead of returning the object from yhe method, you can return its index and then remove by index:
int idx = methodToGetObjectIndexFromA();
Object X = A.remove(idx); // But this part is time consuming, as I unnecessarily loop through A
B.add(X);
However, note that the remove method may be still slow due to potential move of the array elements.
You can use an iterator, and if performance is an issue is better you use a LinkedList for the list you want to remove from:
public static void main(String[] args) {
List<Integer> aList = new LinkedList<>();
List<Integer> bList = new ArrayList<>();
aList.add(1);
aList.add(2);
aList.add(3);
int value;
Iterator<Integer> iter = aList.iterator();
while (iter.hasNext()) {
value = iter.next().intValue();
if (value == 3) {
bList.add(value);
iter.remove();
}
}
System.out.println(aList.toString()); //[1, 2]
System.out.println(bList.toString()); //[3]
}
If you stored all the objects to remove in a second collection, you may use ArrayList#removeAll(Collection)
Removes from this list all of its elements that are contained in the
specified collection.
Parameters:
c collection containing elements to be removed from this list
In this case, just do
A.removeAll(B);
When exiting your loop.
Addition
It calls ArrayList#batchRemove which will use a loop to remove the objects but you do not have to do it yourself.
I want to remove all elements in ArrayList that are duplicates of the first element, but I want the firs element to remain in the ArrayList. I tried to do that with for loop, but it didn't remove all duplicates.
for(int i = 1; i < arraylist.size(); i++) {
if(arraylist.get(i) == v1)
arraylist.remove(i);
}
v1 is equal to the first element of the arraylist.
I also tried with ListIterator, but it removed the first element
ListIterator<Integer> iterator = arraylist.listIterator();
while(iterator.hasNext()) {
if(iterator.next().intValue() == v1)
iterator.remove();
}
Can you please help me?
You need to read the first element separately, outside the while loop, and store it in some variable, with which you would compare the rest of the elements, to remove:
ListIterator<Integer> iterator = arraylist.listIterator();
int first = 0;
// Check if there is a first element
if (iterator.hasNext()) {
first = iterator.next();
// Iterate over the rest of the elements
while(iterator.hasNext()) {
// If this value is equal to `first`, remove it
if(iterator.next().intValue() == first) {
iterator.remove();
}
}
}
System.out.println(arrayList);
iterator.next() will return a value of type Integer. Using intValue() will give your primitive value out.
But since I'm doing the comparison with an int primitive itself, you won't need to call intValue() at all. Your Integer will automatically be unboxed to primitive int before comparison. So, replacing the if statement in while with the below one will also work:
if(iterator.next() == first) {
iterator.remove();
}
As far as your first way is concerned, I would say, always use Iterator if you want to modify the List you are looping upon. This will prevent you from facing awkward ConcurrentModificationException.
See also:
Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop
You are doing the correct way by using Iterator and its method remove. But you should add a call to next() before the loop itself, in order to go over the first element and not remove it.
ListIterator<Integer> iterator = arraylist.listIterator();
iterator.next(); // pass the first element.
while(iterator.hasNext()) {
if(iterator.next().intValue() == v1)
iterator.remove();
}
Contrary to what others have said, you don't have to use "equals" if v1 is an int, which seems to be the case.
Count down (not up):
Object v1 = arraylist.get(0);
for (int i = arraylist.size() - 1; i > 1; i--) {
if (arraylist.get(i).equals(v1))
arraylist.remove(i);
}
You have to count down because as you remove elements, they the remaining ones shuffled down.
Also, you should change == to .equals() (as shown).
int v1 = arraylist.get(0);
for(int i = 0; i < arraylist.size(); i++) {
if(arraylist.get(i) == v1){
arraylist.remove(i);
i--;
}
}
If you don't want to use the Iterator approach: The other answers are correct in that you need to index from zero (if you want to remove the first one as well), but you also need to decrement your iteration variable (the i-- line) each time you remove an element from the list, because you're changing the list's length with remove().
It's best to be careful about removing elements from an array (or an iterable list) whilst iterating over it.
Easiest approach, in my experience, is to create a new list. Can you consider doing that?
Looking at your code, firstly remember to use "equals" over "==" for comparison (since .equals means "meaningfully equivalent", which I think is what you need here). (edit: may not matter here due to autoboxing, but it's still a nice habit to have)
But even this won't work:
for (int i = 1; i < arraylist.size(); i++) {
if (arraylist.get(i).equals(v1))
arraylist.remove(i);
}
Since imagine you have an ArrayList of three integers, all the same. When i == 1, The element at index 1 is compared to the value at index 0, and removed. But then the element at index 2 becomes the element at index 1, the for-loop counter is incremented, thereby "missing" to remove the last entry in the list.
Can I recommend something like this?
List<Integer> newlist = new ArrayList<Integer>();
newlist.add(v1);
for (Integer integer : arraylist) {
if (!integer.equals(v1))
newlist.add(integer);
}
Best of luck!
P.S. if you're feeling brave, you might be able to do a neat one-liner out of this:
CollectionUtils.filter(Collection,Predicate)
CollectionUtils.filter(arraylist.subList(1, arraylist.size()), new Predicate() {
#Override
public boolean evaluate(Object o) {
return !v1.equals(o);
}
});
I'm a relatively new Java programmer and I'm having difficuly removing more than one element from an ArrayList. Ideally I'd like to do something like this:
ArrayList ar1 = new ArrayList();
ar1.add(...)
ar1.add(...)
ar1.add(...)
ar1.add(...)
for (int i = 0; i < 2; i++){
ar1.remove(i);
}
I think iterator might help, but I can't find an example that matches close enough to what I'm trying to do. Any help would be appreciated. Thanks.
Here's what you want to do:
ar1.subList(0, 2).clear();
This creates a sublist view of the first 2 elements of the list and then clears that sublist, removing them from the original list. The subList method exists primarily for this sort of thing... doing operations on a specific range of the list.
You can certainly do that
ArrayList ar1 = new ArrayList();
ar1.add("a");
ar1.add("b");
ar1.add("c");
ar1.add("d");
for (int i = 0; i < 2; i++) {
ar1.remove(i);
}
System.out.println(ar1);
Only pay attention that after you remove first element, other elements shift. Thus, calling
ar1.remove(0);
ar1.remove(1);
will effectively remove first and third elements from the list. This will delete first two elements, though:
ar1.remove(0);
ar1.remove(0);
For indexed removals from a list, you need to count backwards:
for (int i = 1; i >= 0; i--)
otherwise, your first removal shifts the items "above" it in the collection and you don't wind up removing the items you think you are removing.
You can use Collection.removeAll(toRemove) if you have a separate list of objects to remove.
http://download.oracle.com/javase/6/docs/api/java/util/Collection.html
If your collection is indexed based, like ArrayList is, you can call
remove(index)
to remove the element at the index. You can do that in a loop, but beware that removing shifts all the indexes as another answer points out.
If all you want to do is remove the first two elements from the list, then
list.remove(0);
list.remove(0);
should do it.
If you know the indexes of the items you want to remove, you can remove them in reverse order, without worrying about shifting indexes:
ArrayList ar1 = new ArrayList();
ar1.add("a");
ar1.add("b");
ar1.add("c");
ar1.add("d");
int[] indexesToRemove = {0,2,3};
Arrays.sort(indexesToRemove);
for (int i=indexesToRemove.length-1; i>=0; i--) {
ar1.remove(indexesToRemove[i]);
}
You could try this:
List<Whatever> l = new ArrayList<Whatever>();
l.add(someStuff);
Iterator<Whatever> it = l.iterator();
int i = 0;
while (i < 2 && it.hasNext()) {
it.next();
it.remove();
i++;
}
Or, more generally:
List<Whatever> l = new ArrayList<Whatever>();
l.add(someStuff);
Iterator<Whatever> it = l.iterator();
while (it.hasNext()) {
Whatever next = it.next();
if (shouldRemove(next)) {
it.remove();
}
}
EDIT: I guess it depends if you are trying to remove particular indices or particular objects. It also depends on how much logic you need to decide if something should be removed. If you know the indices then remove them in reverse order. If you have a set of Objects to be removed, then use removeAll. If you want to iterate over the list and remove objects that match a predicate then use the above code.