Some times java.util.ConcurrentModificationException thrown - java

I executing below code but some times i got java.util.ConcurrentModificationException exception..But some times working fine.please let me know where i did wrong code.Below is my code please check my logic also if there is any better way then let me know.
public String saveSkills(HttpServletRequest request,#RequestParam String skills,#RequestParam String Email) throws IOException
{
Domain domain1 = (Domain)request.getSession().getAttribute("Domain");
Long domanId =domain1.getDomainId();
System.out.println(skills);
String[] skillsParts = skills.split(",");
UserProfile user = userProfileManager.getUserByEmail(domain1.getPrimary_Domain_Id(), Email);
if(user.getSkillsList().size()>0){
Iterator it = user.getSkillsList().iterator();
while (it.hasNext())
{
Skills skillsitereator = (Skills) it.next();
int count=0;
for(int i =0;i<skillsParts.length;i++){
if((skillsParts)[i].equals(skillsitereator.getSkillName())){
break;
}else{
count++;
}
}
if(count == skillsParts.length){
it.remove();
userProfileManager.update(user);
}
}
}else{
for(int i =0;i<skillsParts.length;i++){
Skills skillObj = new Skills();
skillObj.setSkillName(skillsParts[i]);
user.getSkillsList().add(skillObj);
}
userProfileManager.update(user);
}
skillsParts = skills.split(",");
System.out.println(skillsParts);
ArrayList<Integer> values =new ArrayList<Integer>();
for(int i =0;i<skillsParts.length;i++){
Iterator it = user.getSkillsList().iterator();
while (it.hasNext())
{
Skills skillsitereator = (Skills) it.next();
if((skillsParts)[i].trim().equals(skillsitereator.getSkillName().trim())){
break;
}
else{
Skills skillObj = new Skills();
skillObj.setSkillName(skillsParts[i]);
user.getSkillsList().add(skillObj);
userProfileManager.update(user);
}
}
}
Gson gson = new Gson();
return gson.toJson(user);
}

This is from the JavaDoc for ConcurrentModificationException:
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.
In your last loop, you sometimes do
user.getSkillsList().add(skillObj);
while iterating using user.getSkillsList().iterator().

ConcurrentModificationExceptions happen when modifying a Collection while iterating it, other than using the Iterator.remove() method.
So, it will be thrown when executing:
user.getSkillsList().add(skillObj);
From the Java Tutorials, The Collection interface :
Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

Related

How do I get Object out of HashMap?

Im trying to get an object out of a HashMap and call a method from this object.
But insted of getting the object, I get a normal java.lang.Object.
public void setExits(HashMap<Direction, Exit> e){
this.exits = e;
Iterator it = e.entrySet().iterator();
while (it.hasNext()) {
Map.Entry exits = (Map.Entry) it.next();
Exit r = exits.getValue(); //HERE I GET ERROR
}
}
You are declaring type constraints in the method signature but in the method body you are not taking any advantage of using the type constraints.
What you are doing is similar to you are using HashMap< Object, Object >. That is why compile error.
Correct Code:
public void setExits(HashMap<Direction, Exit> e){
this.exits = e;
Iterator<Map.Entry<Direction, Exit>> it = e.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Direction, Exit> entry = it.next();
Exit r = entry.getValue(); // OK
}
}
Change this line:
Iterator it = e.entrySet().iterator();
to:
Iterator<Entry<Direction, Exit>> it = e.entrySet().iterator();
Here is how I might iterate every value in a HashMap
HashMap<Directive, Exit> tempHashMap = new HashMap<>();
for(Directive directive:tempHashMap.keySet()){
Exit tempExit = tempHashMap.get(directive);
//do what you want with the exit
}
You are using a HashMap like a list. It's not a very effective list.
Instead do
Object value = map.get(key);
And it will skip the items that aren't under the key, very efficiently.
public void setExits(HashMap<Direction, Exit> exits, Direction direction){
this.exits = e.get(direction);
}
What you have missed is the generics for the Map.Entry.
It looks to me as though you are trying to loop over all the entries of the map, you might find a for loop easier.
for(Map.Entry<Direction, Exit> entry : e.entrySet()) {
Direction dir = entry.value();
//do stuff
}

Getting java.util.ConcurrentModificationException in Iterator

I am trying to iterate custom object using iterator and adding data into that custom object but when size of object is 1 it's working but when I am adding second data it gives me an error : nested exception is java.util.ConcurrentModificationException
My Code is as Follow :
public List<ValidationObject> _validationObjects = new ArrayList<>();
public void addError(String key, String value){
int size = _validationObjects.size();
if(size==0){
ValidationObject vo = new ValidationObject();
vo.setKey(key);
vo.addLine(value);
_validationObjects.add(vo);
}
else{
Iterator i = _validationObjects.iterator();
while(i.hasNext()){
ValidationObject obj = (ValidationObject)i.next();
if(obj.getKey().equals(key)){
obj.addLine(value);
}else{
ValidationObject vo = new ValidationObject();
vo.setKey(key);
vo.addLine(value);
_validationObjects.add(vo);
}
}
}
}
In class ValidatioObject I have variable as follow :
private List<String> _lines;
private String _key;
I am calling addError() method as follow :
list.addError("Name", "Should not empty");
list.addError("Prefix", "Should not empty");
Any Help on it, why it's behaving like this.
I think you need to change the logic. Add to your list outside the iterator
else{
boolean keyFound = false;
Iterator i = _validationObjects.iterator();
while(i.hasNext()){
ValidationObject obj = (ValidationObject)i.next();
if(obj.getKey().equals(key)){
obj.addLine(value);
keyFound = true;
}
}
if(!keyFound){
ValidationObject vo = new ValidationObject();
vo.setKey(key);
vo.addLine(value);
_validationObjects.add(vo);
}
}
Why this exception is because of this line,
_validationObjects.add(vo);
beacuse,
If the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
So try adding that using the iterator instance only.
Define a ListIterator and add to that,
ListIterator i=_validationObjects.listIterator();
i.add(vo);

Is it possible to get the index of a for-each loop in Java

Given the code below, is it possible to remove the index of p from the properties list using this style of for loop in Java?
List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";
for(Properties p : propertiesList) {
if(p.getKey().equals(keyToDelete)) {
propertiesList.remove(index) //How to remove the element at index 'p'
}
}
This is how i would accomplish this with the other for loop
List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";
for(int i = 0; i < propertiesList.size(); i++) {
if(p.getKey().equals(keyToDelete)) {
propertiesList.remove(i);
}
}
The way to do this is with an explicit Iterator (no school like the old school!).
Iterator<Properties> it = propertiesList.iterator();
while (it.hasNext()) {
if (it.next().getKey().equals(keyToDelete)) {
it.remove();
}
}
Unlike the remove method on a list, the remove method on the iterator doesn't cause a concurrent modification. It's the only safe way to remove an element from a collection you're iterating over. As the javadoc for that method says:
The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.
No, you need to use the old-school for loop to get an index.
You could of course add it yourself to the for-each loop, but then you would most probably be better off using the old variant instead.
How about using proper Iterator and its remove method?
List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";
for (
Iterator<Properties> iter = propertiesList.iterator( );
iter.hasNext( );
)
{
Properties p = iter.next( );
if(p.getKey().equals(keyToDelete)) {
iter.remove( );
}
}
As Tim Anderson suggested you could also modify the list outside the loop
List<Properties> propertiesList = new ArrayList<Properties>();
String keyToDelete = "blah";
List<Properties> propertiesToRemove = new ArrayList<Properties>();
for(Properties p : propertiesList) {
if(p.getKey().equals(keyToDelete)) {
propertiesToRemove.add(p) ;
}
}
propertiesList.removeAll(propertiesToRemove);
As far as I know, foreach loop does not guarantee the order of elements it enumerates,
so if you will try Collection[i] you can get another element rather than currently iterated
It is can be clearly viewed in some multithreaded cases

How do I remove an object from an ArrayList in Java?

I have an ArrayList that contains some object, such as User, and each object has a name and password property. How can I delete only the User object that has a specific 'name' from this ArrayList?
Iterator<User> it = list.iterator();
while (it.hasNext()) {
User user = it.next();
if (user.getName().equals("John Doe")) {
it.remove();
}
}
You could use something like this:
// If you are using java 8
userList.removeIf(user-> user.getName().equals("yourUserName"));
// With older version
User userToRemove = null;
for(User usr:userList) {
if(usr.getName().equals("yourUserName")) {
userToRemove = usr;
break;
}
}
userList.remove(userToRemove);
Another thought: If User class can be uniquely defined by the username and if you override equals with something like:
public boolean equals(Object arg0) {
return this.name.equals(((user) arg0).name);
}
You can remove the User without iterating through the list . You can just do :
list.remove(new User("John Doe"))
You are probably faced with the ConcurrentModificationException while trying to remove object from the List. An explanation for this exception is that the iterator of the ArrayList is a fail-fast iterator. For example, it will throw an exception (fail) when it detects that its collection in the runtime has been modified. The solution to this problem is to use the Iterator.
Here is a simple example that demonstrate how you could iterate through the List and remove the element when specific condition is met:
List<User> list = new ...
for (Iterator<User> it = list.iterator(); it.hasNext(); ) {
User user = it.next();
if (user.getUserEmail().equals(currentUser.getUserEmail())) {
it.remove();
}
}
Recommended way to solve this problem is:
ArrayList<User> list = new ArrayList<User>();
list.add(new User("user1","password1"));
list.add(new User("user2","password2"));
list.add(new User("user3","password3"));
list.add(new User("user4","password4"));
Iterator<String> iter = list.iterator();
while (iter.hasNext())
{
User user = iter.next();
if(user.name.equals("user1"))
{
//Use iterator to remove this User object.
iter.remove();
}
}
Using Iterator to remove an object is more efficient than removing by simply typing ArrayList(Object)
because it is more faster and 20% more time saving and a standard Java practice for Java Collections.
You could:
loop over the list with an iterator
check if each item in your list is the right user (checking the name)
if it is, use the remove method of the iterator.
Just search through the ArrayList of objects you get from the user, and test for a name equal to the name you want to remove. Then remove that object from the list.
Your code might look like this:
List<User> users = new ArrayList<User>();
public void removeUser(String name){
for(User user:users){
if(user.name.equals(name)){
users.remove(user);
}
}
}
ArrayList<User> userList=new ArrayList<>();
//load data
public void removeUser(String userName){
for (User user: userList){
if(user.getName()equals(userName)){
userList.remove(user);
}
}
}

How can I make an iterator that never ends?

I was just wondering what the easiest way to iterate over a set indefinitely, i.e. when it reaches the end it next(); calls the first object. I'm assuming that this is not an already predefined function in Java, so just looking for the easiest way to implement this in Java.
There's a method in the excellent Google Collections library which does this:
Set<String> names = ...;
Iterable<String> infinite = Iterables.cycle(names);
(I can't recommend the Google Collections library strongly enough. It rocks very hard. I'm biased as I work for Google, but I think pretty much every Googler writing Java would tell you how useful the collections are.)
Iterator it = mylist.iterator();
while (it.hasNext())
{
MyType t = (MyType)it.next();
// do something
if (!it.hasNext())
it = mylist.iterator();
}
Try EndlessIterator from Cactoos:
Iterator<String> names = new EndlessIterator<>("John");
It will always return "John" and will never end.
Also, check EndlessIterable, which implements Iterable and does the same.
If you're making the iterator, in the next method you can have an if condition that checks if there's another object in the list. If there is, then you return that object, if there isn't then you go back to the start of the list and return that object.
This is what I can think of...
iterator = set.getIterator
//other code
if (iterator.hasNext())
//do code here
else
iterator = set.getIterator();
How about ?
List<String> list = // ArraysList
Interator<String> it = null;
while(true) {
it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
If you don't want to use Guava but still want a reusable solution:
public static class CyclicIterator<E, C extends Collection<E>> implements Iterator<E> {
final private C mElements;
private Iterator<E> mIterator;
public CyclicIterator(C elements) {
mElements = elements;
mIterator = elements.iterator();
}
#Override
public boolean hasNext() {
if (! mIterator.hasNext()) {
mIterator = mElements.iterator();
}
return mIterator.hasNext();
}
#Override
public E next() {
if (! mIterator.hasNext()) {
mIterator = mElements.iterator();
}
return mIterator.next();
}
}
Note: this doesn't support the remove() method but it could easily be added if needed. Also it's not thread safe.
I think what you want never help You can do anything with your iterator that's easy but you must be carefull with any new thing you add im not used with this style but this is what you want though :
if (! It.hasNext() )
{
while ( It.hasPrevious() )
{
It = It.Previous();
}
} else {
It = It.Next();
}
This way is nothing if your really interested you should instead make next pointer of the last to the first always when pushing a new list.
std jdk:
Iterable<String> infinite = Stream.generate(names.stream()).flatMap(e -> e).iterator()

Categories

Resources