Thomas (boggyb) wrote,
Thomas
boggyb

Every puzzle has an answer

Bonus extra post, to avoid talismancer mocking the lack of content today. That said, he hasn't updated yet today...

There's been a few guesses at monday's Java puzzler. talismancer is right in that the code won't work. olego and pteppic took this a bit further, and correctly guessed that it'd throw an exception of some sort. Specifically, you get the following output:

Adding java.lang.Object@addbf1 at index 0
Adding java.lang.Object@42e816 at index 1
Adding java.lang.Object@9304b1 at index 2
Adding java.lang.Object@190d11 at index 3
Adding java.lang.Object@a90653 at index 4
Adding java.lang.Object@de6ced at index 5
Adding java.lang.Object@c17164 at index 6
Adding java.lang.Object@1fb8ee3 at index 7
Adding java.lang.Object@61de33 at index 8
Adding java.lang.Object@14318bb at index 9
Removing java.lang.Object@addbf1
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
	at java.util.AbstractList$Itr.next(Unknown Source)
	at Foo.emptyBarList(Foo.java:15)
	at Foo.main(Foo.java:24)

Line 15 is for (Object o : barList) {

At first this seems like an odd place to get an exception - there's no obvious code in this line. But it makes sense when you realise that the Java compiler rewrites that line into something like:

Iterator<Object> it = barList.iterator(); while (it.hasNext) {Object o = it.next();

Most of the standard Java collections explicitly state that structural modifications to the collection will generally cause any iterators to throw a ConcurrentModificationException. Fortuantly there is a way round this: you're permitted to modify the list via methods on the iterator object (like Iterator.remove()). The concurrent collections also won't throw an exception, as the iterators in those are designed to be fully thread-safe and cope with (but don't necessarily show the result of) structual changes.

The fix in this case is easy enough: rewrite the loop to explicitly create an Iterator object and call the remove() method on that. And then add a unit test so that the method is actually tested, rather than being left as a hidden bug until someone does a completely unrelated change and actually adds code to call it!

Tags: java, nablopomo, puzzle
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 1 comment