

Java 7 - What's new? Release date, code examples and performance - alrex021
http://inebium.com/post/java-7-new-release-performance-code

======
lenni
I'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
The 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/0...](http://mail.openjdk.java.net/pipermail/coin-
dev/2009-March/001193.html)

~~~
abalashov
Why 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
Because it solves the problem mentioned above i.e. the compiler's choice of
which type of container to create becomes straightforward.

~~~
sesqu
If 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).

------
aphyr
There'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>

~~~
ericlavigne
The 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
This 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-
variabl...](http://stackoverflow.com/questions/271440/c-captured-variable-in-
loop) [http://stackoverflow.com/questions/233673/lexical-
closures-i...](http://stackoverflow.com/questions/233673/lexical-closures-in-
python)

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
To 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
Ah 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
Yeah, 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.

~~~
ericlavigne
I actually think that will change in Java 7. I will likely not be using "for"
very often, and will start using higher-order functions like map and fold. The
issue is mainly developers for whom closures are a new concept. If they are
too confused as they make their first nervous steps into the world of
functional programming, if their first attempts at using closures result in a
lot of bugs, then they may write off the whole thing as more complicated than
it's worth.

------
vlisivka
If 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
Or use Google Collections in Java 1.5 or higher.

<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
> Or use Google Collections in Java 1.5 or higher.

See Sandman reply.

------
Dellort
Where can I go for more benchmarks?

