Java - weird ConcurrentModificationException [duplicate] - java

This question already has answers here:
Java Set gets full
(2 answers)
Closed 8 years ago.
I loop through a copy of a set of objects, but it still gives me an error starting at this method:
private static Set<Updated> updates = new HashSet<>();
public static Set<GameObject> getGameObjects() {
Set<GameObject> objs = new HashSet<>();
for (Updated up : new HashSet<Updated>(updates)) {
if (up instanceof GameObject)
objs.add((GameObject) up);
}
return objs;
}
(Where the for loop is).
This only happens when there are quite a few GameObjects, and never occurs when there's only a few (like 7). Thank you!

The problem is that somebody in another thread changes the updates set while it is being copied in new HashSet<Updated>(updates).
You cannot do this without synchronization. Or use ConcurrentHashMap instead of HashSet

Related

ConcurrentModificationException -> How can I change my code to stop it from throwing this error? [duplicate]

This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 5 years ago.
for (FPlayer p : fPlayer.getFaction().getOnline()) {
p.setFaction(null);
}
Basically, the getOnline method returns an array list of the current FPlayers that are online. When the FPlayer is removed from their faction, the faction is set to null (p.setFaction(null)).
I cannot think about how to change my code to stop it from throwing the ConcurrentModificationException. I have used an iterator but still, it.next().setFaction(null) still throws the same exception.
EDIT:
USING A LIST ITERATOR:
ListIterator<FPlayer> it = fPlayer.getFaction().getOnline().listIterator();
while (it.hasNext()) {
it.next().setFaction(null);
}
Caused by: java.util.ConcurrentModificationException
At the line
it.next().setFaction(null)
EDIT #2:
Set faction method:
public void setFaction(Faction faction) {
if (hasFaction()) {
this.faction.getOnline().remove(this);
}
this.faction = faction;
if (faction != null) {
this.faction.getOnline().add(this);
}
}
This is happening because while iterating you are removing the data from the list .
Couple of solutions .
If the list size is small convert it to array and then loop over
Use for loop for iteration .
for(int i=0;i<fPlayer.getFaction().getOnline().size();i++)
{
// Condition to check if true
if(true)
{
fPlayer.getFaction().getOnline().remove(i);
i--;
}
}
Yes, change your code so it doesn't change the collection inside the loop you are running. For example, create a copy of the collection before iterating.
for (Foo foo : new ArrayList(myFoos)) {
if (foo.isBar()) {
myFoos.remove(foo);
}
}
Iterating and changing the list without the new ArrayList() would have caused a ConcurrentModificationException

Add List Throws java.lang.UnsupportedOperationException [duplicate]

This question already has answers here:
Java List.add() UnsupportedOperationException
(8 answers)
Closed 5 years ago.
I have 4 functions with same get...() method, and I only change the name or identifier, but I've got different result with the fourth which is when to adding new item to list, it throws java.lang.UnsupportedOperationException. I assure you, I've already double checked all 4 functions and their relations, but have no idea why the fourth function like this.
public List<PropertyAttribute> getAttributes() {
if (selectedCode == null)
return null;
Criteria criteria = this.propertyAttributeDAO.createCriteria();
FilterUtils.byField(criteria, "propertyCode", this.selectedCode, true);
List<PropertyAttribute> list = criteria.list();
if (isNewAttribute()) {
list.add(0, this.curAttribute); //this line that throws exception
}
return list;
}
UPDATE STACK TRACE:
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at bos.web.pages.instrument.ViewProperty.getAttributes(ViewProperty.java:654)
at $InternalPropertyConduit_237587e282284.get(Unknown Source)
at org.apache.tapestry5.internal.bindings.PropBinding.get(PropBinding.java:59)
Unless it's clearly documented, don't assume it's safe to modify a list you received from another method. Even if it doesn't throw an exception, it may be altering critical state (if it's not implemented safely). Copy it to a new list and you can do whatever you like:
List<PropertyAttribute> list = new ArrayList<>(criteria.list());

java.util.ConcurrentModificationException - How do I delete using an iterator [duplicate]

This question already has answers here:
How to avoid java.util.ConcurrentModificationException when iterating through and removing elements from an ArrayList
(24 answers)
Closed 5 years ago.
Using the following code will result in a java.util.ConcurrentModificationException
final AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long timestamp) {
for (ListIterator<myCircle> List = CircleList.listIterator(); List.hasNext(); ) {
myCirle check = List.next();
if (CheckCollisionFunction(check) == true) {
this.stop();
CircleList.clear();
gameOverFunction();
}
}
}
}
So im using an iterator to check if any of my circles are colliding with my player circle.
When I clear the list:
CircleList.clear();
I get the exception.
java.util.ConcurrentModificationException
Which is when you delete sometimes outside an iterator when using an iterator. Can someone please show me how to delete everything in my list using the iterator?
Or another way to stop this error.
This is my list.
private final ObservableList<myCircle> CircleList = FXCollections.observableArrayList();
Simply insert a break; after gameOverFunction(); to stop the iterator.
The problem is that you clear the list, but the iterator continues, and on the next next() call the exception will be thrown.

ConcurrentModificationException in iterator.next() Multithreaded [duplicate]

This question already has answers here:
ConcurrentModificationException when using iterator and iterator.remove()
(4 answers)
Closed 6 years ago.
I have created this simple worker thread to calculate palindromes by iterating through an ArrayList.
I get an Error when I execute line temp_str1 = it.next();.
The ArrayList buffer_List is not used by any other thread hence using synchronized block does not help. I have looked through previous questions and they did not help much. I would eager to find the solution to this problem.
Here is My code:
private void find_Palindromes(ArrayList<String> buffer_List){
Iterator<String> it = buffer_List.iterator();
String temp_str1, temp_str2;
while(it.hasNext()){
temp_str1 = it.next();
//System.out.println(temp_str1);
it.remove();
if(is_Palindrome(temp_str1)){
to_Shared_Queue(temp_str1);
palin_count++;
}
}
}
Edit Code : added to_Shared_Queue
private void to_Shared_Queue(String str){
synchronized(shared_queue){
Shared_queue.add(str);
}
}
It is because of you modifying iterator while looping over it . you can do it by remove it from your array buffer_List.
buffer_List.remove(temp_str1);

Java ArrayList collection to hold latest 5 additions [duplicate]

This question already has answers here:
Fixed size queue which automatically dequeues old values upon new enqueues
(15 answers)
Closed 8 years ago.
I have an extra ordinary requirement of having a Java object array list (or list initialized as an ArrayList) which will be continuously updated and is supposed to hold only the latest 5 items with the objects to be sorted in a descending order of they were added.
How could this be accomplished? I need to come up with a solution within Java SE 7 preferably using no 3rd party library.
NOTE For those who mark this question as a duplicate, you do not seem to understand the requirement of using ArrayList for this case and that Queues and ArrayLists are different object types as well as Java and C# are different languages. Do you think Stackoverflow's internal search engine is not as good as you are in locating the duplicate questions?
When marking a question as "duplicate", make sure you link a true duplicate, please.
Not sure about the descending order, but this shows one way of fixing the size
class BoundedArrayList<E> extends ArrayList<E> {
private int fixedCapacity;
public BoundedArrayList(int fixedCapacity) {
super(fixedCapacity);
this.fixedCapacity = fixedCapacity;
}
#Override
public boolean add(E e) {
// is it about to cross limit ? removing it in advance
if(this.size() > fixedCapacity - 1) {
E element = this.remove(fixedCapacity - 1);
System.out.println("Removed due to overflow : " + element);
}
this.add(0, e);
return true;
}
public static void main(String[] args) {
BoundedArrayList<Integer> list = new BoundedArrayList<Integer>(5);
for(int i =0 ; i < 10; i++) {
list.add(i);
System.out.println(list);
}
}
}

Categories

Resources