• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Jeanne Boyarsky
  • Junilu Lacar
  • Henry Wong
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Frits Walraven
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • salvin francis
  • fred rosenberger

Iterate and delete TWO items without concurrent modification exception...

 
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello dear ranchers!
I have the following problem I am trying to solve elegantly.
I did it with two stacks, but I want to iterate on a linkedlist and remove two items if they are the same. Of course I get concurrent modification exception. Any nice rancher care to help ?

 
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How many Iterators have you got? What scope does the Iterator have? What you are doing is creating the Iterator before you add anything to the List, then you will get a concurrent modification exception. You need to narrow the Iterator's scope.

In C it was necessary to declare local variables at the beginning of the “function”, but you don't have to do that in Java®. As a general design principle however, declare local variables as late as possible before they are used. What's more, all the books show how to use a while loop with Iterators, but a for loop has the advantage of reducing the Iterator's scope:-Now the add() calls occur when the Iterator hasn't been declared yet, so there is no problem about overlapping scope.
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You also mustn't try removing from the List (line 22) while there is an Iterator in scope. Look up ListIterator#remove() and ListIterator#removeNext().

[additional]If you find that removeNext() doesn't exist, try a second next() followed by remove().
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Campbell,
I don't get it, do you mean I should get two iterators, or one iterator and remove next and remove next next?
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try two Iterators and tell us what happens; that should provoke some interesting exceptions
You need a next next after the next which isn't the next next then after the next next you can have a next remove.
 
Rancher
Posts: 4588
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't create the iterator at the start.
You don't need it until after you've populated the List, so get the iterator after line 16.

That's your problem, and that's what Campbell is saying.

When you create the iterator it is for that empty List.  You then add stuff to the List, and then iterate...at which point the iterator throws the exception as the underlying List has changed since the iterator was created.
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jokes apart, let's alter your code a bit:-I think I have made a mistake. If you run out of numbers, try changing line 7 to to it.previous();
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can simplify lines 27‑32:-I used valueOf() to make sure the middle and right operands for ?: both have the same type.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had NO IDEA you could do that:

Looks much better, but now it jumps out the loop and print impossible even when Simone should be able to pair the socks...
(I did change to previous and it gives the same error)

Intressting to sort out what it is )
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

D.J. Quavern wrote:I had NO IDEA . . .

It isn't in the books, is it? And do the books warn you that an Iterator might not go out of scope if you use while?

Intressting to sort out what it is )

You will have to put some debugging in the loop to see what is happening. At least I don't have to explain you it, because I know you know how to do debugging already.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ugh, I stepped trough it and can't figure it out, even with assigning it.next(), it.previous() and so on ://
*frustration is growing already*
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you printing the whole List? Are you using the xxxIndex() methods?
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No I tried to navigate my way only with ite.previous() and iter.next().
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You need lots more debugging information than that.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your help, I'll be back with a better try
 
Marshal
Posts: 15638
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would have used stacks instead of lists for this problem.
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
DJ did say earlier that she got it to work with stacks.
 
Junilu Lacar
Marshal
Posts: 15638
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

D.J. Quavern wrote:I had NO IDEA you could do that:


None of the clauses of the for-loop header are required. You can even leave all of them out:

That for-loop is equivalent to this
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Junilu! You came to see some ugly code     ?
I was aware of that, but not that you could declare an iterator in a for loop... but it makes sense, since you can declare an int...?

For Junilu greatest joy (of dissecting horrific code), here I post the working code with stacks.



 
Bartender
Posts: 3959
155
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

D.J. Quavern wrote:For Junilu greatest joy (of dissecting horrific code)


Are you sure? Never noticed...    

But you do not need the counting. Why? (And you can do with just one list and no iterator)
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:

D.J. Quavern wrote:For Junilu greatest joy (of dissecting horrific code)


Are you sure? Never noticed...    



He spends a lot of time dissecting it, so it must be fun somehow....

Piet Souris wrote:But you do not need the counting. Why? (And you can do with just one list and no iterator)


What do you mean? I do, according to the problem description. I must return the "number of moves".
 
Saloon Keeper
Posts: 12027
257
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't use the Stack class. It extends Vector, which has become pretty much obsolete. Instead, use the Deque interface, which you can instantiate with an ArrayDeque or a LinkedList. If you use Deque purely as a stack, ArrayDeque is appropriate. If you want to use a ListIterator to move forwards and backwards to delete and insert stuff, then LinkedList is a good choice.

Where does InputReader come from?

Don't declare variables before you need them.

Don't use negative logic in your if-else-statements. Just switch the clauses around.

You can get rid of the provisory.empty() check in your while-loop. If provisory is empty and old is not, then old.peek() will never equal provisory.peek().

You increment your counter in both the then-clause and the else-clause. Instead, increment it outside of your if-statement. You can do the same with the old.pop() expression: Call it before your if-statement.

I like that when transferring a 'sock' from one stack to the other, you save it in a temporary variable of type Integer. Normally we recommend against the use of primitive wrappers, but seeing as the integer just represents an equatable property of the sock and you don't have to perform any numeric operations, using Integer avoids unnecessary boxing and unboxing. Well done. As an alternative, you could have made your class generic so you can use equatable properties of any type.

Don't do everything in main(). Model your problem, no matter how small it is. Here's what I did:
 
Stephan van Hulst
Saloon Keeper
Posts: 12027
257
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

D.J. Quavern wrote:What do you mean? I do, according to the problem description. I must return the "number of moves".


Piet's point is that you can calculate the number of moves without counting them.
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Don't use the Stack class. It extends Vector . . .

One of the mistakes made in the early days of Java® collections, as Tim H hinted in another post today..I think they have never got stacks right, and only will if they introduce a Stack<E> interface with the methods push() pop() peek() size() and isEmpty().
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you a lot for all the tips! I need to review them carefully a few times, but there is a lot I did not suspect (about stacks for example). Good to be with experts. I ran your code in Kattis Stefan, it's faster.

I don't model those problems, since it's those who require very short solutions (making a proper solution just put you at disadvantage with others)... Piet, you who did a lot of hackerrank, you know what I mean, help me out here

And how do you calculate without counting (Piet)?

InputReader is a class by William Fiset that I use for competitive programming: https://github.com/williamfiset/FastJavaIO
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

D.J. Quavern wrote:. . . I don't model those problems . . .

I can tell; you would never have said that seating two boys at the dinner table so they can't fight is an NP‑complete problem.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

D.J. Quavern wrote:. . . I don't model those problems . . .

I can tell; you would never have said that seating two boys at the dinner table so they can't fight is an NP‑complete problem.


I meant that I *minimally* model those problems! Not down to classes.

Wait, how'd you know they are two   ? Maybe calculating the number of brothers is itself NP?
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If there are four of them, there is a subset of two; if there are three, there is still a subset of two
 
Piet Souris
Bartender
Posts: 3959
155
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi DJ,

first of all: I totally disagree with Stephan. These exercises are not meant to develop and train your OOP capabilities. I remember starting with exercises at Peoject Euler and HackerRank and the like. I did it the OOP way, to the best of my abilities. But when I showed my solutions, full of pride, I saw I was facing three to four line Python solutions. I really felt like the laugh of the town. My motto is now: Quick and Short, Dirty not being a problem. And with Java, keeping things short is already quite demanding.

A funny thing was: I was doing my first exercise at Hyperskiil the other day. It was a simple exercise, but to give it a little more effort, I used List.of and similar. But all of it was rejected, so I complained that I had no clue whether I needed to do imports, and what java was supported, and the like. And then I got a reply to do it in a simpler way.    

But about calculating: suppose there is a pair in the pile that can be retrieved. Now, for this you need: a) move the first sock to pile 2, and when sock two is in top of the first pile, retrieve both socks, taking another move. So that means we have to do two moves for one pair. Now, the pile contains 2N socks, and if there is a solution, we retrieve N pairs, taking ... moves!

Another way to go is: first: we remove all pairs that are consecutive in the pile. For instance: if socks 2 and 3 are equal, we remove them. We then end up with a pile that may contain pairs, but these pairs are not consecutive, since these were removed. What condition must be satisfied to have a solution, and how would you implement all this?
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Piet Souris wrote:hi DJ,

Another way to go is: first: we remove all pairs that are consecutive in the pile. For instance: if socks 2 and 3 are equal, we remove them. We then end up with a pile that may contain pairs, but these pairs are not consecutive, since these were removed. What condition must be satisfied to have a solution, and how would you implement all this?



Go through a list and remove consecutive/identical numbers. My nightmare!!
 
Sheriff
Posts: 7108
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But you can do this in your mind, right?  So think about how you would explain this to a five-year-old.  Then "translate" that explanation into Java.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I probably can explain it to a 5 year old, but I know I will have indice problems and edge cases in java 😭!
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well explain it to me and I shall pass on the explanation to our local five‑yea‑old, assuming she hasn't got worn out by going back to school.
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Hello Louissy,
First put all the cubes with numbers in a row like a train.
You have to go through the list of cubes, and if you see two cubes that have the same number, like twin-number cubes, take them out of the train.
When you took all the twin cubes out, see if there are cubes left. If no, you won."
 
Campbell Ritchie
Marshal
Posts: 69495
277
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
She doesn't answer to Louissy
So, are you looking up and down the “train” to find cubes with the same number? Won't that take longer than two piles? Why didn't you say socks and colours?
 
D.J. Quavern
Master Rancher
Posts: 303
16
IntelliJ IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:She doesn't answer to Louissy
So, are you looking up and down the “train” to find cubes with the same number? Won't that take longer than two piles? Why didn't you say socks and colours?



I thought it was a hypothetical 5 year old, so I gave her my neighbours 5 year old name . What's the name then ?

We are speaking about a list now so I thought she will understand better with cubes.
Yes, works better with piles, but solving it with piles is not a problem. The cube train is.
 
machines help you to do more, but experience less. Experience this tiny ad:
Devious Experiments for a Truly Passive Greenhouse!
https://www.kickstarter.com/projects/paulwheaton/greenhouse-1
    Bookmark Topic Watch Topic
  • New Topic