java.util.ConcurrentModificationException while removing items from collection [duplicate] - java

This question already has answers here:
List.remove strange behaviour
(4 answers)
Closed 7 years ago.
I am learning Java's Collection framework. I wrote this little program to check why we can't use For-each to remove elements.
Code:
import java.util.ArrayList;
class intro{
public static void main(String args[]){
ArrayList<String> names = new ArrayList<String>();
names.add("Rajat");
names.add("Saxena");
for(String name:names){
names.remove(name);
}
for(String name:names){
System.out.println(name);
}
}
}
Outputs:
Saxena
And
import java.util.ArrayList;
class intro{
public static void main(String args[]){
ArrayList<String> names = new ArrayList<String>();
names.add("Rajat");
names.add("Saxena");
names.add("Arvind");
for(String name:names){
names.remove(name);
}
for(String name:names){
System.out.println(name);
}
}
}
Throws:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at intro.main(intro.java:15)
How come just the addition of one more element to collection is causing the error?

Normally when you remove an element from a collection while looping over the collection, you'll get a ConcurrentModificationException. This is partially why the Iterator interface has a remove() method. Using an iterator is the only safe way to modify a collection of elements while traversing them.
The code would go something like this:
ArrayList<String> names = new ArrayList<String>();
names.add("Rajat");
names.add("Saxena");
names.add("Arvind");
for (Iterator<String> iterator = name.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
iterator.remove();
}
}

Related

Iterating through collections to add items but throwing ConcurrentModificationException

package com.ripal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class Outputs {
public void show() {
final ArrayList<String> list = new ArrayList<String>();
list.add("banana");
list.add("apple");
Iterator<String> itr = list.iterator();
Collections.sort(list);
while (itr.hasNext()) {
System.out.println(itr.next() + " ");
}
}
}
class Test {
public static void main(String[] args) {
Outputs outputs = new Outputs();
outputs.show();
}
}
ArrayList has a fail fast iterator. You can modify the collection only via the iterator. Any other modification done outside is detected sooner after calling the iterator methods and a ConcurrentModificationException is thrown. In your case after creating the iterator you sort the array in place and that sorting routine modifies the contents of the array, leading to ConcurrentModificationException upon using the iterator. To fix the issue, just perform the sorting before you create the iterator. Here's how it looks.
Collections.sort(list);
Iterator<String> itr = list.iterator();

Concurrent Modification Exception while adding elements to ArrayList recursively

Getting Concurrent Modification Exception while adding elements to ArrayList recursively.
import java.util.*;
public class Hello {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(gss(str));
}
public static ArrayList<String> gss(String str) {
if(str.length() == 0){
ArrayList<String> list = new ArrayList<String>();
list.add("");
return list;
}
ArrayList<String> list = gss(str.substring(1));
for(String temp : list){
list.add(str.charAt(0)+temp); // Problem
}
return list;
}
}
Solution: To just form new ArrayList at each call stack and return it.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(gss(str));
}
public static ArrayList<String> gss(String str) {
if(str.length() == 0){
ArrayList<String> list = new ArrayList<String>();
list.add("");
return list;
}
ArrayList<String> list = gss(str.substring(1));
ArrayList<String> listToReturn = new ArrayList<>();
for(String temp : list){
listToReturn.add(temp);
}
for(String temp : list){
listToReturn.add(str.charAt(0) + temp);
}
return listToReturn;
}
}
I have recently come across this blog.
Which says, It uses a transient variable called modCount, which keeps track of how many times a list is modified structurally. Structural modifications are those that change the size of the list, which may affect the progress of iteration and may yield incorrect results. Both Iterator and ListIterator uses this field to detect unexpected change. Other methods of List which structurally modify List also uses this method e.g. add(), remove().
Cause: The real cause of ConcurrentModficationException is inconsistent modCount. When you are iterating over ArrayList then Iterator's next() method keep track of modCount. If you modify the collection by adding or removing element then modCount will change and it will not match with the expected modCount, hence Iterator will throw ConcurrentModificationException.

Cannot remove hashset in java [duplicate]

This question already has answers here:
Why is a ConcurrentModificationException thrown and how to debug it
(8 answers)
Closed 8 years ago.
i got a problem with hashset, I cannot remove a hashset, and here is the code
//take stopword list from file
public void stopWordList(){
openFile("D:/ThesisWork/Perlengkapan/stopword.txt");
while(x.hasNext()){
String a = x.nextLine();
a = a.toLowerCase();
stopWords.add(a);
}
}
//the method to remove stopword
public void stopWordRemoval(){
stopWordList();
//if the word in the streams set is equal to stopword, it should be removed
for(String word:streams){
for(String sw:stopWords){
if(word.equals(sw)){
streams.remove(word);
}
}
}
But, it gives me an exception, it says like :
Exception in thread "main" java.util.ConcurentModificationException, could anyone help me? thanks :)
This is because the foreach loop (for (Whatever x: something)) internally creates an Iterator.
And when you remove from the Iterable (the something above) being iterated, a well-behaved Iterator will detect that "hey, you have modified my babies beyond my knowledge" and throw this exception.
What you should do is this:
final Iterator<String> iterator = stream.iterator();
String word;
while (iterator.hasNext()) {
word = iterator.next();
if (stopWords.contains(word))
iterator.remove(); // This is safe: an iterator knows how to remove from itself
}
you are performing a concurrent modification - you are iterating over a collection and modifiying it not by the iterator, you should transform your code to this:
for (Iterator<String> it = streams.iterator(); it.hasNext();) {
String word = it.next();
for (String sw : stopWords) {
if (word.equals(sw)) {
it.remove();
break;
}
}
}

java+ ConcurrentModificationException forEach(enhanced) loop single thread [duplicate]

This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
ConcurrentModificationException for ArrayList [duplicate]
(6 answers)
Closed 9 years ago.
I am not able to understand the reason, why the below code is throwing CME, even when this is run as single thread application
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModification {
public static void main(String[] args) {
ConcurrentModification con = new ConcurrentModification();
con.call();
}
void call() {
List<Integer> l = new ArrayList<Integer>();
for (int i = 0; i <= 10000; i++) {
l.add(i);
}
for (Integer j : l) {
if (j % 3 == 0) {
l.remove(j);
}
}
}
}
Reason:(after going through the answer and other links)
You are not permitted to mutate a list while you are iterating over it.
Only Iterator remove's method can be used to delete element from list
For Each loop is using iterator beneath it
but l.remove(j) is not using that iterator, which causes the exception
You are not permitted to mutate a list while you are iterating over it. Your l.remove(j) causes the list l to change, but you're inside a for (Integer j : l) loop.
For this you need to use iterator
for (Iterator<ProfileModel> it = params[0].iterator(); it
.hasNext();) {
ProfileModel model = it.next();
DBModel.addProfile(homeScreenActivity, model, profileId);
}
I used it to add data in database..Hope it helps

How do I update the element at a certain position in an ArrayList? [duplicate]

This question already has answers here:
Java ArrayList replace at specific index
(6 answers)
Closed 4 years ago.
I have one ArrayList of 10 Strings. How do I update the index 5 with another String value?
Let arrList be the ArrayList and newValue the new String, then just do:
arrList.set(5, newValue);
This can be found in the java api reference here.
list.set(5,"newString");
Reference
arrList.set(5,newValue);
and if u want to update it then add this line also
youradapater.NotifyDataSetChanged();
import java.util.ArrayList;
import java.util.Iterator;
public class javaClass {
public static void main(String args[]) {
ArrayList<String> alstr = new ArrayList<>();
alstr.add("irfan");
alstr.add("yogesh");
alstr.add("kapil");
alstr.add("rajoria");
for(String str : alstr) {
System.out.println(str);
}
// update value here
alstr.set(3, "Ramveer");
System.out.println("with Iterator");
Iterator<String> itr = alstr.iterator();
while (itr.hasNext()) {
Object obj = itr.next();
System.out.println(obj);
}
}}
arrayList.set(location,newValue);
location= where u wnna insert, newValue= new element you are inserting.
notify is optional, depends on conditions.

Categories