6 ms·
Java 7 - What's new? Release date, code examples and performance
- aphyr 17y agoThere's a lot of good stuff here--notably the (finally) decent support for literal sets, arrays, and maps in JSON style... but most importantly, closures! I am so sick and tired of creating one-off anonymous classes just to pass a function around. Unfortunately you can only use them with final variables. Ah, well... http://blogs.sun.com/mr/entry/closures http://blogs.sun.com/mr/entry/closures http://blogs.sun.com/mr/entry/closures http://blogs.sun.com/mr/entry/closures
- ericlavigne 17y agoThe top priority is still to avoid confusing programmers, and closing over non-final variables can lead to some very confusing situations. For example: List list = Lists.newArrayList(); for(Integer i = 0; i < 10; i++) { list.add(fn [x] { i + x }); } Think you just created a list of 10 functions that each add a different number to their argument? If you closed over the i variable, that variable changed and by the end of the loop is 9. All of the functions return their argument plus 9. In any case, I can't wait to get some form of closures in Java. Best case would be to get a job using a decent programming language, but closures and various data type literals could go a long way to dull the pain until then.
- extension 17y agoThis certainly does appear to be a common point of confusion for languages that have both mutable variables and closures: http://stackoverflow.com/questions/271440/c-captured-variable-in-loop http://stackoverflow.com/questions/271440/c-captured-variabl... http://stackoverflow.com/questions/233673/lexical-closures-in-python http://stackoverflow.com/questions/233673/lexical-closures-i... I remember bumping into the issue myself in JavaScript, but only once. After I became aware of the concept, it was never a problem again, in any language. Those one-time issues don't worry me. It's the problems that come up over and over again that are worth fixing at the language level. A good way to explain it is to analogize captured variables to variables used in the body of a loop or conditional. Variables are only ever created when a declaration is evaluated, and a variable has exactly one value at any given time. The obvious alternative, copying the variable when it's closed over, seems more confusing to me. And the current restriction, that captured variables are final, is just going to force hackery. Ultimately, if Java grunts want closures, they will have to understand variable capturing. It's part of the package.
- _delirium 17y agoTo me the confusion is more with the loop constructs. My mental model is fine with variable capture in general, but I don't interpret loop variables as "real" variables. What I'd intuitively expect, if I didn't already know that most languages don't do it that way, is that the loop variable is freshly bound on each iteration. That expectation is strengthened by the fact that a lot of languages seem not to want to allow you to actually use it as a real variable anyway: you often can't modify the loop variable within a foreach-style loop, which leads me to view them as fresh immutable bindings per iteration. Admittedly, the Java for loop is a plain C-style for loop, where you actually can modify the loop variable if you wish, so it pretty much has to work that way. But the binding-reuse behavior of, say, Python's for i in range(n) loop makes less sense to me. IIRC, it's also one of the many contentious differences in Common Lisp between the LOOP and ITERATE macro packages.
- extension 17y agoAh yes, it is a problem if a language is not clear about the lifetime semantics of a loop variable. In Ruby, for example, an idiomatic loop like 10.times{|i| ... } does indeed bind a new variable for every iteration, but that is implicitly clear to anyone with a basic understanding of the language. Likewise, the 3-part for loop of Java et al does not hide the fact that it's the same variable every time through the loop. The Java for-each loop, on the other hand, is more ambiguous. A quick check seems to indicate that the iterator variable can be declared final and captured in an anonymous inner class. That means that for-each acts differently than for loop and I could see that confusing your average code monkey.
- _delirium 17y agoYeah, I think the main thing that's confusing about the particular example given in this thread is that the common case of looping over integers usually intends a foreach-style loop, but Java syntax doesn't make it easy to do something like for(final int i : Range(1,10)). So people end up using the C-style 3-part for loop when they don't have any real need for its power.
- deleted 17y ago[deleted]
- RodgerTheGreat 17y agoI would read it.
- Dellort 17y agoWhere can I go for more benchmarks?
- vlisivka 17y agoIf you cannot wait for Java 1.7, use usual trick with anonymous classes and static initializer block: Java 1.7: List<String> list = ["item"]; Java 1.2: List<String> list = new AList<String>() {{ items=["item"]; }}; where: public class AList<T> implements List<T> { protected T[] items; // Implementation } Set<String> set = {"item"}; Set<String> set = new ASet<String>() {{ items={"item"}; }}; Map<String, Integer> map = {"key" : 1}; Map<String, Integer> map = new AMap<String, Integer>() {{ keys=["key"]; values=[1]; }}; I can post detailed explanation and examples of this technique, which I love to use, in my blog, if somebody will be interested. (English is foreign language to me). It is much better than to use full blown implementation and bunch of setters just to pass around one or two elements. I often use this technique to pass optional data to/from methods or to program in declarative style in java.
- ericlavigne 17y agoOr use Google Collections in Java 1.5 or higher. http://code.google.com/p/google-collections/ http://code.google.com/p/google-collections/ List<String> list1 = Lists.newArrayList("item"); List<String> list2 = Lists.newArrayList("item1","item2"); Of course, none of these workarounds are close to what Java 7 offers. Just a few more months :-)
- vlisivka 17y ago> Or use Google Collections in Java 1.5 or higher. See Sandman reply.
- Sandman 17y agoFor lists, you can also do this: List<String> strings = new ArrayList<String> (Arrays.asList("one", "two", "three"));
- vlisivka 17y agoYes, you right. This is very cheap way to initialize ArrayList. I use it too. Did you know something similar for Map's? :-)
- lenni 17y agoI'm wondering how the implementation is chosen when you do something like List<String> list = ["ham","eggs"]; Is it a linked list, an array list, a vector ... ?
- _delirium 17y agoThe compiler chooses, probably based on the type and number of elements. In theory it should know how to do this efficiently, because this syntax returns only immutable collections, so the compiler knows up front exactly what the collection will ever contain. This is what the proposal says about that decision: It is likely to be higher in space and time performance, in that the compiler can choose efficient implementations for small collections (such as empty collections and singletons). On the other hand, it is less flexible, in that you cannot specify the implementation type. From: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001193.html http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/0...
- abalashov 17y agoWhy does it only return immutable collections? Because the spec says so, or because there is some principle suggesting that it should? Personally, my first instinct was to read the syntax as a form of initialisation, not something that would bar me from adding or deleting elements after the set is instantiated.
- extension 17y agoBecause it solves the problem mentioned above i.e. the compiler's choice of which type of container to create becomes straightforward.
- sesqu 17y agoIf the choice would be a mutable one, making it expressly immutable after the fact serves no purpose. As it is, the compiler gets to choose an efficient list for the data provided, and then refuse to compromise on that efficiency later. You might as well use an enum. What useful collection implementation would require immutability? Even arrays are more flexible. Sure, it's nice syntax, but I can come up with more scenarios where I'll want to initialize a collection than scenarios where I want to finalize one (well, excepting for the fact that this is java, where immutability is often considered a virtue).