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

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

Related

ConcurentModificationException while adding items in a map [duplicate]

This question already has answers here:
Why is a ConcurrentModificationException thrown and how to debug it
(8 answers)
Closed 2 years ago.
I am facing java.util.ConcurrentModificationException while adding items to an existing list corresponding to a key
Here is my code
final Map<String, List<Apple>> feedToApplesMap = new HashMap<>();
for (final Apple Apple : AppleList) {
final List<String> feedDocumentIds = Apple.getFeedDocumentIds();
for (final String feedId : feedDocumentIds) {
final List<Apple> AppleListForFeed = feedToApplesMap
.getOrDefault(feedId, new ArrayList<>());
AppleList.add(Apple);
feedToApplesMap.put(feedId, AppleListForFeed);
}
}
I am unable to use iterator to solve this ? Any suggestions ?
I agree with #andbi that the question is due to a typo. But just for the exception, By doing so for (final Apple Apple : AppleList) you are still using Iterator unintentionally, that's why here AppleList.add(Apple); will throw ConcurrentModificationException, you can do it like this to avoid using Iterator:
final Map<String, List<Apple>> feedToApplesMap = new HashMap<>();
int size = AppleList.size();
for (int i = 0; i < size; i++) {
final Apple Apple = AppList.get(i);
final List<String> feedDocumentIds = Apple.getFeedDocumentIds();
for (final String feedId : feedDocumentIds) {
final List<Apple> AppleListForFeed = feedToApplesMap
.getOrDefault(feedId, new ArrayList<>());
AppleList.add(Apple);
feedToApplesMap.put(feedId, AppleListForFeed);
}
}
Please be aware that enhanced for-loop is just a syntatic sugar for for-loop with Iterator, the following two are the same:
for (Iterator<T> i = c.iterator(); i.hasNext(); )
for (T t : c)
Here is the document: The For-Each Loop
It seems like you're storing apples in a wrong place. Shouldn't it be
AppleListForFeed.add(Apple) instead of AppleList.add(Apple) ?
This happens when we are iterating a list using for loop or for each and some elements are added in between during iterating so use iterator or iterating a list:
val iterator = yourList.iterator()
while (iterator.hasNext()) {
val currentItem = iterator.next()
}
now add or delete any other element in your list during iterating.

Removing all elements from map that does not match leads to java.util.ConcurrentModificationException [duplicate]

This question already has answers here:
Why is a ConcurrentModificationException thrown and how to debug it
(8 answers)
Closed 2 years ago.
I wrote the following code:
for (Character currentChar : userDocuments.keySet()) {
List<QueryDocumentSnapshot> currentList = userDocuments.get(currentChar);
if (currentList == null) {
userDocuments.remove(currentChar);
continue;
}
for (int index = 0; index < currentList.size(); ++index) {
final String currentFullName = currentList.get(index).getString("full_name");
if (currentFullName == null || !(searchText.contains(currentFullName))) {
currentList.remove(index);
}
}
if (currentList.size() == 0) {
userDocuments.remove(currentChar);
}
}
I want to iterate over a map Map<Character,List<QueryDocumentSnapshot>> check if the full_name (field of each QueryDocumentSnapshot) contains searchText and if it's not, remove this element from the list. In case list is empty, remove the entire list. But for some reason I get java.util.ConcurrentModificationException on the first line. Also, how can I use contains without case sensitive?
The ConcurrentModificationException occurs when an object is tried to be modified concurrently when it is not permissible. This exception usually comes when one is working with Java Collection classes. For Example - It is not permissible for a thread to modify a Collection when some other thread is iterating over it.
In your case, it is arising coz you are trying to remove some elements from both the Map and ArrayList while iterating over them.
You can avoid it using:
Iterator<Map.Entry<Character, List<QueryDocumentSnapshot>>> mapIterator = userDocuments.entrySet().iterator();
while (mapIterator.hasNext())
{
Map.Entry<Character,List<QueryDocumentSnapshot>> entry = mapIterator.next();
List<QueryDocumentSnapshot> currentList = entry.getValue();
if (currentList == null) {
mapIterator.remove();
continue;
}
Iterator<QueryDocumentSnapshot> listIterator = currentList.iterator();
while (listIterator.hasNext()) {
final String currentFullName = listIterator.next().getString("full_name");
if (currentFullName == null || !(searchText.contains(currentFullName))){
listIterator.remove();
}
}
if (currentList.size() == 0) {
mapIterator.remove();
}
}
And to answer your question 'how can I use contains without case sensitive' , you can simply use something like this:
searchText.toLowerCase().contains(currentFullName.toLowerCase())

for loop comparison over enhanced for loop in concurrent modification exception

I was reading about concurrent modification exception and noticed in case of element removal using enhanced for loop throws concurrent modification exception whereas normal for loop doesn't.
Can someone please help me understand why this is happening, below code
import java.util.ArrayList;
import java.util.List;
public class ConcurrentModificationExceptionExample {
public static void main(String args[]) {
List<String> myList = new ArrayList<String>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
myList.add("5");
// enhanced for loop
/* for(String s:myList){
if(s.equals("1")){
myList.remove("1");
}
}*/
// normal for loop
for(int i = 0; i<myList.size(); i++){
if(myList.get(i).equals("1")){
myList.remove("1");
}
}
System.out.println(myList);
}
}
for testing //enhanced for loop can be uncommented
This is because in your "normal for loop" code no Iterator is involved. Instead, you access the elements individually with get.
The loop notation
for (String s: myList) {
...
}
creates an iterator object behind the scenes. The iterator keeps track of collection modifications. When you make a modification without using the iterator you will get a ConcurrentModificationException.
When using
for (int i = 0; i < myList.size(); i++) {
...
}
and accessing the collection with
myList.get(i)
there is no iterator created, and therefore no chance for the exception to be thrown.

HashMap iterating and deleting element [duplicate]

This question already has answers here:
Why is a ConcurrentModificationException thrown and how to debug it
(8 answers)
Closed 4 years ago.
public void execute(HashMap<String,Coordonnee >c)
{
c.forEach((k,v) -> {
p = m.getMin(c);
sky.add(p);
c.remove(p.getNom());
});
}
This throws a java.util.ConcurrentModificationException.
How can I fix that ?
Use removeIf function:
map.entrySet().removeIf
Use iterator:
Iterator<Object> it = map.keySet().iterator();
while (it.hasNext())
{
it.next();
if (something)
it.remove();
}
you cannot delete an element of the list while looping through it. You should use Iterator for that.
public void execute(HashMap<String,Coordonnee >c)
{
Iterator cItr = c.iterator();
while(cItr.hasNext())
{
c = cItr.next();
p = m.getMin(c);
sky.add(p);
cItr.remove(p.getNom());
}
}

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;
}
}
}

Categories