This question already has answers here:
Why doesn't this code throw a ConcurrentModificationException?
(3 answers)
Closed 7 years ago.
I have following code -
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1a");
list.add("2b");
for (String s : list) {
list.remove(s);
}
System.out.println("Removed");
System.out.println(list);
}
}
If I run this program, I expect it should throw exception but the output is "2b". If it is running fine then why It is not removing the last object.
Again If I add more element in the list It is thorwing exception java.util.ConcurrentModificationException Which is expected.
My question is -
Why it is not removing all the elements from list if we have 2 elements in the list ??
Why the java.util.ConcurrentModificationException exception occur only when we have more elements ?? I tried a lot of time with two elements.
I am using Java 8.
Thanks in advance.
Actually, when you are removing 1a from the list, the size is getting reduced, and you now have only 1 element in the list, thus the loop does not execute the second time, there by resulting in the keeping the second element.
Related
This question already has answers here:
How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? [duplicate]
(10 answers)
Closed 3 years ago.
I can be the implementation of a chat app to show users chat only the can get user_id to be sent or receive a message to store in user-list and select the user to be added in the list some error like a User list if added user 1 and add user 2 when and user 1 again the exception in ArrayList
for (String id : usersList)
if (equal(user.getId(), id)) {
if (mUseres.size() != 0) {
for (User user1 : mUseres) {
if (!equal(user.getId(), user1.getId())) {
mUseres.add(user);
}
}
} else {
mUseres.add(user);
}
The issue is here:
for (User user1 : mUseres) {
if (!equal(user.getId(), user1.getId())) {
mUseres.add(user);
}
You are iterating mUseres (for....) and at same time you are adding new items (mUseres.add)
You cant modify the List while iterating through it.
From the docs
Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have to get the first element of an array., but it is possible that the element is empty; If the element is empty I put an empty field (I am trying to generate a pdf)
Here is my code now:
public void makePdf(Long id) throws IOException {
Candidacy ca = candidacyRepository.findOne(id);
cos.beginText();
cos.showText(
ca.getInterviews().stream().map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0)!=null?ca.getInterviews().stream().map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0):""));
cos.endText();
}
So I will wish not to prevent the generation of the pdf.
Thank you very much for your support!
UPDATE
Sorry for the lack of precision:
I also sort on the date.
public void makePdf(Long id) throws IOException {
Candidacy ca = candidacyRepository.findOne(id);
cos.beginText();
cos.showText(
ca.getInterviews().stream().sorted((a,b)-> a.getInterviewDate().compareTo(b.getInterviewDate())).sorted((a,f)->f.getInterviewDate().compareTo(a.getInterviewDate())).sorted((b,f)->b.getInterviewDate().compareTo(f.getInterviewDate())).map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0)!=null?ca.getInterviews().stream().sorted((a,b)-> a.getInterviewDate().compareTo(b.getInterviewDate())).sorted((a,f)->f.getInterviewDate().compareTo(a.getInterviewDate())).sorted((b,f)->b.getInterviewDate().compareTo(f.getInterviewDate())).map(Interview::getAgency).map(Agency::getAgencyName).collect( Collectors.toList()).get(0):""));
cos.endText();
}
I get a NullPointerException:/
Thank you for you help
This code doesn't make sense. You are executing the same Stream pipeline twice, and each time you generate an entire List when you only need the first element of that List.
You can use findFirst to get the first element of the Stream.
EDIT :
After testing my original answer, it turned out it doesn't work. findFirst() throws a NullPointerException if the first element is null.
You can avoid that by setting the default value before calling findFirst() :
ca.getInterviews().stream()
.map(Interview::getAgency)
.map(Agency::getAgencyName)
.map(s->s!=null?s:"") // this will replace null with ""
.firstFirst()
.get();
This question already has answers here:
Calling next on an Iterator once vs multiple times
(3 answers)
Closed 7 years ago.
I had some trouble with the whole iterator concept and for a question in one of my quizzes, I honestly couldn't understand what was up.
public static void main(String[] args)
{
Deque<String> SQ1 = new ArrayDeque<String>();
SQ1.add("Give");
SQ1.add("Me");
SQ1.add("The");
SQ1.add("Best");
SQ1.add("Of");
SQ1.add("Both");
SQ1.add("Worlds");
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
if(It.next().equals("Give"))
System.out.print(It.next());
}
}
This is the code, and the question is what will be the output. The correct answer is "Me" when I thought it was "Give". I don't understand how the whole run goes.
This is what I understand:
It does have a next. If that next equals "Give", it will print out that next value. In this case, that value should be "Give", shouldn't it?
Could someone please help me understand this?
The if-statement calls It.next() to check the value, and the the print statement calls It.next() again, rather than printing the value that you just checked.
So what you see will always be the element directly after "Give".
The correct answer is "Me" when I thought it was "Give". I don't understand how the whole run goes.
Right, the code is illustrating a common error. The error is that the code is telling the iterator to advance to the next item and give it to us twice:
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
if(It.next().equals("Give"))
// here^^^^^^^^^
System.out.print(It.next());
// and here -------------^^^^^^^^^
}
So it's getting the value, seeing if it's "Give", and then if that value was "Give" it throws it away and gets the next value, which in your test data is "Me". (Note that if "Give" were the last entry, that second call to next would throw an error, since there would be no next entry at that point.)
To "fix" it and have it show "Give", still using that kind of loop, you'd remember the result of the call in a variable, and then use the variable in those two places:
Iterator<String> It = SQ1.iterator();
while(It.hasNext())
{
String value = It.next();
if(value.equals("Give"))
System.out.print(value);
}
But, this is what the enhanced for loop is for: You don't use an It variable at all, just:
for (String value : SQ1) {
if(value.equals("Give"))
System.out.print(value);
}
As you can see from the Java docs:
next
E next()
Returns the next element in the iteration.
Returns:
the next element in the iteration
Throws:
NoSuchElementException - if the iteration has no more elements
So your call:
If(It.next().equals("Give"))
Actually returns the "next" value and sets the Iterator 'It' to the next one in your ArrayDeque.
If you call next again you will be one step further.
This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 7 years ago.
my Java (libgdx) application/game throws me java.util.ConcurrentModificationException.
My code:
for (Lod lod : lode) {
if (!pause){
lod.move();
}
if (lod.isDestroyed()){
lode.remove(lod);
} else {
lod.draw(game.batch);
}
}
You try to remove an element while you are iterating over the collection. This is simply not possible by the iterator.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I have an a ChoiceBox that lists months values, when the user choose a value, it execute this lambda expression:
private TableView<IncomeFX> tableIncome;
private ChoiceBox<Month> choiceBoxIncomeMonths;
private ChangeListener<Month> setChoiceBoxIncomeMonthsBehaviour(){
ChangeListener<Month> months = (ObservableValue<? extends Month> observable, Month oldValue, Month newValue) -> {
incomesData.clear();
Year selectedYear = choiceBoxIncomeYears.getSelectionModel().getSelectedItem();
ObservableList<IncomeFX> temp = incomeManager.getIncomesOf(selectedYear, newValue);
incomesData.addAll(temp);
};
return months;
}
and how i add the listener:
choiceBoxIncomeMonths.getSelectionModel().selectedItemProperty().addListener(setChoiceBoxIncomeMonthsBehaviour());
when I click on the choicebox, i get:
Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:386)
at java.util.AbstractList$Itr.next(AbstractList.java:355)
at java.util.AbstractCollection.addAll(AbstractCollection.java:343)
at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:99)
at lite.money.ui.MainUI.lambda$1(MainUI.java:160)
at lite.money.ui.MainUI$$Lambda$120/1680764266.changed(Unknown Source)
it indicate that the problem is in the line where I call: addAll(temp)
how can i solve this ??? thanks
Since you haven't posted all the code, I'm going to guess you are running code on another thread that is trying to interact with the JavaFX data. When another thread tries to do this, it will throw an exception since only the JavaFX thread should be interacting with the data.
I can't really offer any more advice because I don't have the full codebase of what you are doing to truly say "yes at line X you are having thread Y access location X when it should not be."
Are you adding this on another thread perhaps? You will know the application better than I would since I don't have anymore code to go off of.
here is how i solve it, it's a bad code i know, but i don't know any other solution, i have to clear it twice or the items will be added like if i didn't clear it, if you do have an other solution i will be happy:
private ChangeListener<Month> setChoiceBoxIncomeMonthsBehaviour(){
ChangeListener<Month> months = (ObservableValue<? extends Month> observable, Month oldValue, Month newValue) -> {
if (!lastMonthValuesFired) {
incomesData.clear();
Year selectedYear = choiceBoxIncomeYears.getSelectionModel().getSelectedItem();
ObservableList<IncomeFX> temp = incomeManager.getIncomesOf(selectedYear, newValue);
ObservableList<IncomeFX> temp2 = FXCollections.observableList(new ArrayList<IncomeFX>());
for (IncomeFX t : temp) {
temp2.add(t);
}
incomesData.clear();
incomesData.addAll(temp2);
}
};
return months;
}
I had the same problem and did some research, this is the solution that I found that worked for me:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* Java Program to demonstrate how to deal with
* ConcurrentModificationException.
* Unlike the name suggests, this error can come even if only
* one thread is modifying the collection e.g. List.
* It happens when you modify collection
* while iterating over it e.g. adding new element or removing elements.
*
* If you want to remove elements while traversing list then
* make sure you use Iterator's remove() method or not ArrayList's remove()
* method() to avoid ConcurrentModificationExcetpion.
*
* #author WINDOWS 8
*
*/
public class ConcurrentModExceptionDemo{
public static void main(String args[]) {
List<String> listOfPhones = new ArrayList<String>(Arrays.asList(
"iPhone 6S", "iPhone 6", "iPhone 5", "Samsung Galaxy 4",
"Lumia Nokia"));
System.out.println("list of phones: " + listOfPhones);
// Iterating and removing objects from list
// This is wrong way, will throw ConcurrentModificationException
for(String phone : listOfPhones){
if(phone.startsWith("iPhone")){
// listOfPhones.remove(phone); // will throw exception
}
}
// The Right way, iterating elements using Iterator's remove() method
for(Iterator<String> itr = listOfPhones.iterator();
itr.hasNext();){
String phone = itr.next();
if(phone.startsWith("iPhone")){
// listOfPhones.remove(phone); // wrong again
itr.remove(); // right call
}
}
System.out.println("list after removal: " + listOfPhones);
}
}
Source