tag:blogger.com,1999:blog-741750605858169835.post1062868172260558616..comments2024-01-24T14:53:02.919+00:00Comments on Stephen Colebourne's blog: Java 7 - For-each loop control accessStephen Colebournehttp://www.blogger.com/profile/01454237967846880639noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-741750605858169835.post-55897111525703129162008-04-28T09:36:36.000+01:002008-04-28T09:36:36.000+01:00The index proposal is just perfect, adding remove,...The index proposal is just perfect, adding remove, isFirst, isLast would really be great.<br /><br />Thanks for following up on the for-each post and the positive feedback in the comments.Dobbynoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-73369127940176010792008-04-28T00:35:23.000+01:002008-04-28T00:35:23.000+01:00For me for.index and for.isLast would solve my 95%...For me for.index and for.isLast would solve my 95% cases and be simple to implement. Of course it would not solve outer loop access but that is fine with me since it is easy to save that in a tmp variable before the inner loop.<br />If you want to go more advanced that it fine too, as long as it doesn't mean I will have to choose between fewer characters and performance and that the simplest case now is not simple and has not much benefit over the original one.Mikael Grevnoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-67055370266016061942008-04-28T00:35:14.000+01:002008-04-28T00:35:14.000+01:00For me for.index and for.isLast would solve my 95%...For me for.index and for.isLast would solve my 95% cases and be simple to implement. Of course it would not solve outer loop access but that is fine with me since it is easy to save that in a tmp variable before the inner loop.<br />If you want to go more advanced that it fine too, as long as it doesn't mean I will have to choose between fewer characters and performance and that the simplest case now is not simple and has not much benefit over the original one.Mikael Grevnoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-49413764439780375802008-04-27T10:31:50.000+01:002008-04-27T10:31:50.000+01:00Lawrence, The main benefit of the direct approach ...Lawrence, The main benefit of the direct approach is performance, which does matter for looping. Bear in mind that array for-each doesn't even generate an Iterator at all ATM. The lookup problem would be solved by IDE code completion for most users.<br /><br />A downside of using a real type for the controller variable is that would normally imply specifying the type in the declaration. I want to avoid that, as it is unecessary duplication, especially with the generics that would be required.<br /><br />One possible solution, would be to have the relevant interface(s), but to allow the compiler to generate direct syntax if it could determine that the variable isn't used for anything special (like passing to another method or reflection). Generally, this kind of optimisation has been left to hotspot, but I suspect that wouldn't be good enough here - a question for the hotspot engineers!Stephen Colebournenoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-63865296597614373962008-04-27T03:14:49.000+01:002008-04-27T03:14:49.000+01:00I really don't like the idea of the "dire...I really don't like the idea of the "direct syntax" (option b). Programmers will have to go to the language spec to look up the set of methods on "it", instead of going to the Javadoc APIs, like they do for everything else. It'll have all sorts of unexpected restrictions, like inability to pass it to another method, cast it to Object, use reflection, etc. IDEs (and all other language parsers) would need all sorts of special support for them. It'll be entirely unlike any other Java variable. I can't imagine that the advantages sufficiently justify it.Lawrence Kesteloothttp://lkesteloot.blogspot.com/noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-12612465382100116382008-04-26T19:14:45.000+01:002008-04-26T19:14:45.000+01:00> You cannot change the existing Iterator inter...> You cannot change the existing Iterator interface - remember interfaces can not evolve and are forever! <br /><br />Ok let me rephrase that, I would love if internal methods of the JDK (or at least of collection) returned an improved Iterator (BoundsIterator or IndexIterator). That would not break existing code the way I see it.Casperhttp://coffeecokeandcode.blogspot.com/noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-13810533727815798272008-04-26T16:01:23.000+01:002008-04-26T16:01:23.000+01:00Stephen, I don't think that compiler-generated...Stephen, I don't think that compiler-generated or -bound types are simpler than using what's already there. I'd challenge your KISS claim in this case.Stefan Schulzhttp://jroller.com/page/jaddanoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-88142758426176749212008-04-26T11:44:39.000+01:002008-04-26T11:44:39.000+01:00Matt, The problem with using a label is that the s...Matt, The problem with using a label is that the scope of the label is not limited to the lifetime of the loop. In addition, adding a new keyword here seems excessive.<br /><br />Dimitar, The document discusses remove on an array (disallowed) and set on an iterable (disallowed, unless it is a List)<br /><br />Brian, An interesting notion, but what happens if you implement both the maps and control proposals. Then you need to allow to obtain the index of the map iteration. I take the view that this is information about the iteration, not part of the iteration itself. Meta-data if you like.<br /><br />Stefan, I have considered allowing dedicated user-provided iterator classes. However, my gut feeling is that they make the concept too complex. This is all about the right level of complexity, and I'm going for KISS here.<br /><br />Kirk, Your #2 can be made to work, but again is fairly complex. In the document, option (b) for implementing the change doesn't require NewIterator at all for example.Stephen Colebournenoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-47326950792477043052008-04-26T11:31:15.000+01:002008-04-26T11:31:15.000+01:00An anonymous comment indicates that you can't ...An anonymous comment indicates that you can't change an existing interface, such as Iterator. That's very true, but you CAN extend it, in a couple of ways:<br /><br />1) If you really wanted to eliminate some forms of backwards compatibility, you could change the signature on return calls, to make, for example, List<> return NewIterator<>, where NewIterator<> extends Iterator<>. The problem here is with all the existing List<> implementations outside of the standard JDK, which would have to be rewritten.<br />2) You could have NewIterator<> extend Iterator<>, and have some implementations return NewIterator<> rather than just a plain Iterator<>. This has the disadvantage that it requires an instanceof and downcast, but it works.<br />3) The next option is to follow the ListIterator<> model and have a separate method to return that (like "NewIterator<> newIterator()").<br /><br />However, the key problem here is that the interfaces involved are already so entrenched that any option other than #2 is going to be extremely difficult to get past all the various implementations of the existing interfaces that rely on Iterator<>.<br /><br />New for loop semantics, however, are NOT prone to this problem, specifically because they can use autobox in conjunction with #2. So imagine that you're in an enhanced-for loop. The code generation can actually automatically grab the Iterator<> and downcast it (or wrap it if it's not a NewIterator<>) so that it presents as a NewIterator<>. So although the interface is immutable, because enhanced-for semantics no matter what can box and wrap up existing code, this would be a relatively safe extension.Kirk Wylienoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-75938539460581128842008-04-26T10:30:56.000+01:002008-04-26T10:30:56.000+01:00Brian's idea is interesting. Instead of adding...Brian's idea is interesting. Instead of adding a colon and an untyped designator/variable, why not optionally allow a second argument before the colon that can take the resulting typed iterator or index, depending on the argument following the colon. This not only would allow to pick some compiler-defined container, but the appropriate one.<br />E.g.:<br />for (Foo value, int index : fooArray) ...<br />for (Foo value, MyFooIterator it : fooList) ...<br />Which may not provide additional features like isFirst or isLast, but is backwards compatible and would require few changes to the for-each implementation. It still would allow for a map-for-each implementation.Stefan Schulzhttp://jroller.com/page/jaddanoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-62244526044481624432008-04-26T09:56:23.000+01:002008-04-26T09:56:23.000+01:00A List or an array is sort of like a map that happ...A List or an array is sort of like a map that happens to be indexed by integers, so it seems like a syntax similar to the proposed for-loop for maps would make a lot of sense:<br /><br />List items = Lists.newArrayList();<br />...<br /> <br />for (int index, Foo value : items) {<br /> System.out.println("item[" + index + "] is " + value);<br />}<br /><br />It doesn't let you remove an entry, but that seems less common than just needing to know the index.Brian Slesinskyhttp://slesinsky.org/brian/noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-39842844669872790522008-04-26T07:48:35.000+01:002008-04-26T07:48:35.000+01:00You cannot change the existing Iterator interface ...You cannot change the existing Iterator interface - remember interfaces can not evolve and are forever!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-86741073059257651892008-04-26T04:18:03.000+01:002008-04-26T04:18:03.000+01:00One possible inconsistence, when introducing itera...One possible inconsistence, when introducing iterator in the for-each construct is that the iterator semantics can not be provided for array.<br /><br />There is no way to really _remove_ an element from array and on the other hand the iterator interface does not let us _replace_ the value that it's pointing to.Dimitar Dimitrovhttp://foobarbazqux.blogspot.com/noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-85970371679543412762008-04-26T03:37:08.000+01:002008-04-26T03:37:08.000+01:00That's a nice KISS improvement. At the same ti...That's a nice KISS improvement. At the same time, I would love if Iterator were equipped with an isFirst - since you often need to perform a special step in the first iteration. Currently, one has to roll his own stuff along the lines of:<br /><br />class BoundsIterator implements Iterator<br />{<br /> private final Iterator iter;<br /> private boolean first = true;<br /> <br /> public BoundsIterator(Iterator iter){ this.iter = iter; }<br /> public boolean hasNext(){ return iter.hasNext(); }<br /> public T next(){ first = false; return iter.next(); }<br /> public void remove(){ iter.remove(); }<br /> <br /> public boolean isFirst(){ return first; }<br /> public boolean isLast(){ return !hasNext(); }<br />}Casper Banghttp://coffeecokeandcode.blogspot.com/noreply@blogger.comtag:blogger.com,1999:blog-741750605858169835.post-79428765838537173292008-04-26T01:26:52.000+01:002008-04-26T01:26:52.000+01:00What about labelling the loop and adding a remove ...What about labelling the loop and adding a remove keyword that would act like it.remove(); continue?<br /><br />loop:<br />for (String str : strings) {<br /> if (str.equals("blah"))<br /> remove loop;<br /><br /> // ...<br />}Matt Mnoreply@blogger.com