

Java 8 Features - ancatrusca
http://www.infoq.com/articles/Java-8-Quiet-Features?utm_source=hackernews&utm_medium=link&utm_campaign=8java_article
If you haven’t seen some of the videos or tutorials around Java 8, you’ve probably been super-busy or have a more interesting social life than I do (which isn’t saying much). With new features like lambda expressions and Project Nashorn taking so much of the spotlight, I wanted to focus on some new APIs that have been a bit under the radar, but make Java 8 better in so many ways.
======
Mister_Snuggles
The new Date API will be a big win for new developers. I think it was created
by the same person that made Joda-Time, so there's some real world experience
behind the new API.

I also like the easy parallelization functions, though as the article
indicates they're not suitable for every use case.

~~~
MrBuddyCasino
Absolutely, good thing they've learned from the java logging disaster. I
nerdrage so hard every time I think about it - how can one mess up something
so basic, yet so important? Maybe some sunny day, they'll fix that too.

~~~
mooism2
I'm curious (it's a long time since I programmed in Java) - what is the java
logging disaster?

~~~
smackfu
Beyond actual capabilities of log4j vs JDK logging, it's not clear that anyone
considered how adoption would work. At the time, log4j supported several back
versions of the JDK, while JDK logging obviously required you to be on the
newest version, v1.4. As a result, if a library wanted to support any older
JDKs, they couldn't switch to JDK logging, or had to support two parallel
logging frameworks for little gain. And if your libraries are sticking with
log4j, what's the advantage to your program of using the JDK logging?

slf4j is the current solution for this kind of problem, a common interface to
various different logging solutions.

~~~
yawz
Logback (next gen log4j): [http://logback.qos.ch/](http://logback.qos.ch/)

~~~
jhawk28
Log4j 2 (next gen logback):
[http://logging.apache.org/log4j/2.x/](http://logging.apache.org/log4j/2.x/)

~~~
deepsun
Curious, why Ceki Gülcü (Log4J author) is no longer in team?

~~~
burkaman
Ceki left Log4J to develop Logback, I think because he felt like he had lost
control of the project.

"For me, starting a new project was a lot worse than just "disheartening". The
SLF4J vote was just the straw that broke the camel's back. After putting many
many hours of work into log4j, it became increasingly painful to waste time in
arguments, where opinions got asserted by the one writing the longest email.
Not fun."

\- [http://mail-archives.apache.org/mod_mbox/logging-
log4j-dev/2...](http://mail-archives.apache.org/mod_mbox/logging-
log4j-dev/200704.mbox/%3C20070404194653.9F87F36CC1@mail.qos.ch%3E)

------
thescrewdriver
The best part is that these classes are available for use in other JVM
languages. I'm more likely to use these from Scala than I am from Java.

~~~
dopamean
I was just thinking the same thing. I'm more likely to use them in Clojure.
Pretty cool.

------
goblue96
I can't wait to do code reviews where people are sprinkling parallelSort() all
over the place, not understanding the consequences.

Serious question: isn't this something the JVM could abstract away?

~~~
bhauer
Good point. There is definitely a challenge of knowing when a single-threaded
collection or stream operation may be preferable to the parallel option. When
my colleague wrote his summary of Java 8 [1], he wrote:

 _Returning to the concept of parallel streams, it 's important to note that
parallelism is not free. It's not free from a performance standpoint, and you
can't simply swap out a sequential stream for a parallel one and expect the
results to be identical without further thought. There are properties to
consider about your stream, its operations, and the destination for its data
before you can (or should) parallelize a stream. For instance: Does encounter
order matter to me? Are my functions stateless? Is my stream large enough and
are my operations complex enough to make parallelism worthwhile?_

The author of the linked InfoQ article (OP) cites that same dilemma by
explaining the potential for context-switching overhead to counter the
advantage of splitting the work.

Abstracting it away with rough heuristics might be possible, but doing so with
consistent success could be challenging. In other words, you could elect to
use the serial algorithm for small collections, or when the CPU contention at
the start of the sort operation is low. But if the comparison operator is
expensive, CPU contention is volatile, or if operating on a stream of unknown
length, the abstraction may choose poorly. Ultimately, I like the option to
choose for myself, but like you, I wouldn't mind having a third option that
defers that choice to some heuristic.

[1] [http://www.techempower.com/blog/2013/03/26/everything-
about-...](http://www.techempower.com/blog/2013/03/26/everything-about-
java-8/)

~~~
MrBuddyCasino
Good point. Something like

    
    
        Arrays.sort(arr, Concurrency.LEVEL)
    

might have been more flexible. Do I want to use the GPU if available? With
which priority should it run, max. performance or more as a background task?

~~~
xxs
GPU won't handle the comparable interface at all. And the memory transfer
CPU<=>GPU would be a true killer. It may work on Direct ByteBuffers only but
that's entirely a different subject.

~~~
MrBuddyCasino
Is that still true with the new unified memory architecture (hUMA) that AMD
introduced? I agree GPUs probably can't handle more complicated comparators
well, but Arrays.sort() could optimize at least for the primitive types.

~~~
xxs
hUMA is brand new and no actual support but in order to work properly the CPU
has to stall waiting for the GPU.

GPU should be interruptible the same way the CPU is, so if the GC decides to
move the memory it can actually do so. The memory can be pinned instead,
though. The latter poses some side effects with the GC. If the GPU is not on
the same die it will have to virtually copy the array as the L1/L2 caches
won't be accessible.

Arrays.sort(somePrimitive[]) would be too much of an edge case to optimize
for. Overall hard nut to crack. Java8 streams and direct buffers, however,
could be a good starting point to perform various operations via the GPU.

Disclaimer: I am really not well versed in the GPU tech.

------
bicx
Wish Android would move in this direction. We're stuck in a 1.6 API for the
most part.

~~~
higherpurpose
Google is not going to try and advance Java development. They should just
deprecate it and switch to Go. But right now they seem stuck in the middle,
not doing either.

~~~
bicx
I really hope they don't. Go is really good for some things, but true object-
oriented languages are great for designing and controlling UIs.

~~~
nkozyra
Hm, I think the way Go uses interfaces would actually be ideal for
manipulation of UI.

~~~
nostrademons
Go also has true closures and easy concurrency support, both of which are very
handy in UI development.

My beef with Go is weak web-programming and prototyping support and immature
libraries. I'm surprised there's been so much uptake in the Ruby/Python
communities, which are very strong in those areas, but I guess Ruby/Python are
now being used outside their original domains and those use-cases are pretty
ripe for a language like Go.

------
ZoFreX
The process control changes might not seem so exciting but they fix some
serious pain points, I'm very excited to integrate these into my code.

Optional is another nice addition, I've been creating one myself in all Java
projects I've created since I first encountered it in Rust.

~~~
meddlepal
My problem with Optional<T> is that it basically makes overloaded Java methods
impossible because of erasure. I'm worried that it is going to start getting
overused; the JDK developers really only intended for its use in the Streams
API.

~~~
tel
Could you explain that a little bit more? I'm using to Maybe from Haskell and
am curious what might be missing from Java's Optional.

~~~
matwood
Basically, because of type erasure you cannot have overloaded methods using
different Optional types. So test(Optional<A> a); is the same method as
test(Optional<B> b);

I think you can define the types to get around it, but that is messy and a
PITA. For example, class OptionalA extends Optional<A>.

~~~
dignati
Wow that's a real pain point. Why would they even do that, is there a use
case?

~~~
ZoFreX
Backward compatibility - you could run an application that uses generics,
introduced in Java 1.5, on a Java 1.4 VM. At the time that was pretty amazing.
These days, with so many backward compatibility-breaking changes being
introduced, it doesn't feel so great.

~~~
mcculley
That was the original plan, but it never worked in my experience. The compiler
as shipped required that -source 1.5 use -target 1.5. So hobbling the language
this way served no benefit in the end.

------
xxs
StampedLocks have been talked about extensively at least on jsr-166 mailing
list and they required adding load/load barrier in sun.misc.Unsafe. That was
the prime reason it needed Java 8, as previously it required a no-op CAS on
the load path.

For most people StampedLock will remain quite a mystery as they are harder to
use and the vact majority of Java developers doesn't actually write (or even
use) low-level concurrency primitives.

~~~
Someone
_" StampedLocks have been talked about extensively at least on jsr-166 mailing
list"_

Isn't that the jsr that designed StampedLock and decided to add it to Java? If
so, I would hope it was talked about extensively, but I wouldn't see such talk
as a counterexample.

~~~
xxs
That's the thing: people who are interested in them (StampedLocks) were
already subscribed on the list. Like I've mentioned - outside there is close
to no interest on low-level primitives, down to CPU memory barriers.

------
mycodebreaks
Which companies are running Java 8 already on production?

~~~
ivan_gammel
For already having it in production it's too early, but definitely there are
companies that have it in near future roadmap. I know couple of them.

~~~
loganekz
Why do you think it's too early?

My company is running it on production with no issues.

------
hyp0
Wouldn't _Mandatory <MyType>_ (or _NonNullable <MyType>_) be better for Java,
since all reference types are nullable (aka optional) already...? Haskell's
Maybe monad doesn't meet java's specific needs.

It could check for null in its _setValue_ method, at write-time - more useful
than discovering it read-time (though I'm not sure it's worth the
abstraction).

~~~
bad_user
In Scala Option[T] works great, as in libraries people stopped using nulls to
represent optional values. And it actually works out when enough people are
using it. Plus, if you're unsure about a value you receive (whether it's
nullable or not), you can always assume the worst and wrap it in an Optional.

------
ChrisAntaki
Secure random generation is exciting, especially for endpoints.

------
gdi2290
Java the good parts?

~~~
saryant
Already been written, though not updated for Java 8:

[http://www.amazon.com/Effective-Java-Edition-Joshua-
Bloch/dp...](http://www.amazon.com/Effective-Java-Edition-Joshua-
Bloch/dp/0321356683)

------
dschiptsov
No one sees an irony?)

~~~
theandrewbailey
How so?

Is it no one is talking about new Java features is because Java isn't the hot
new web stack or JS library? Or because most big Java users move to new things
with the speed of continental drift?

~~~
smoyer
We're a big Java user but apparently faster - our current environment is
JavaSE 7 and JavaEE 6. We'll move to JavaEE 7 when there is commercial support
for an application server (probably JBoss EAP 7.0.0) and will likely allow
Java SE8 at the same time.

We're quite a bit slower at migrating existing applications (except for
security issues), but because we code defensively, we are generally backwards
compatible.

------
terranstyler
Re Optional<T>:

If I get this right, the source code of the signature of many (many!) methods
will now be twice the size of before, unless the names of your types and
variables were already considerably bigger than "Optional<...>" (10 chars).

I hope it's worth this cost.

~~~
wicknicks
Yeah, I hope I am interpreting this the wrong the way. But instead of doing

    
    
      X.getA().getB().getC().getD()
    

we have to

    
    
       X.flatMap(X::getA)
        .flatMap(X::getB)
        .map(X::getC)
        .orElse("UNKNOWN");  //[1]
    

Not sure why this is going to be better?

[1]
[http://www.oracle.com/technetwork/articles/java/java8-option...](http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html)

~~~
necubi
That's not a fair comparison, as the flatMaps are eating nulls (really
Optional.empty()s) while the naked calls will throw NPEs. The equivalent code
for the first case is:

    
    
      String result = "UNKNOWN";
      T a = X.getA();
      if (a != null) {
        T b = a.getB();
        if (b != null) {
          String c = b.getC();
          if (c != null) {
            result = c;
          }
        }
      }
    

Optional (like Scala's Option or Haskell's Maybe) are useful because they
force you to reason about "empty" cases. Whereas in typical java code there is
no way for the compiler to force to you handle the possibility of nulls (thus
leading to NPEs), Wrapping a type in Optional forces you to deal with the case
where the result is not present, leading to more correct programs. Plus, it
gives you handy tools for dealing with non-present values, like allowing a
chain of computation--any step of which may fail--without needing failure
checks on every step.

------
leorocky
> The difference between this and the old Atomics is that here, when a CAS
> fails due to contention, instead of spinning the CPU, the Adder will store
> the delta in an internal cell object allocated for that thread.

Wow man Java's still all in with it's terrible threading mechanism all the
while C# has had async, await and parallelism for years, Go is well past
version 1 to great acclaim, node.js and libuv are taking over, and Akka has
gained enormous popularity and yet real coroutines in Java aren't even on the
horizon. Even python 3 is getting coroutines.

Low level threads in Java are so goddamned awful and unavoidable that it makes
me want to pull my hair out. And I otherwise love Java. Java would be so
awesome with real, native coroutines. Like that should be only thing they
should be working on right now.

Edit:

I'm guessing the people downvoting this have no idea what I'm talking about
and don't know what coroutines are.

You know I'm starting to think there's maybe an entire generation of Java
engineers who have no idea how much easier it is to write concurrent code with
other tools and Java has ruined them. I love Java, but expand your horizons a
bit.

~~~
bad_user
> _C# has had async, await and parallelism for years_

For Scala developers, there's Scala Async, which is exactly what C# "async"
is, implemented as a library:
[https://github.com/scala/async](https://github.com/scala/async) \- plus
Scala's `Future[T]` has a better design than C#'s Task.

> _node.js and libuv are taking over_

And both suck in comparison with Java's NIO and the libraries that have been
built on top of it.

> _Low level threads in Java are so goddamned awful and unavoidable that it
> makes me want to pull my hair out_

Low level concurrency primitives are necessary for building higher-level
abstractions on top. For example I need low level concurrency primitives for
implementing a Reactive Extensions (Rx) implementation that does back-
pressure:
[https://github.com/alexandru/monifu/](https://github.com/alexandru/monifu/)

> _the people downvoting this have no idea what I 'm talking about and don't
> know what coroutines are_

You're assuming too much.

~~~
Locke1689
_plus Scala 's `Future[T]` has a better design than C#'s Task_

Why? The one issue I have with Task is the aggravating
SynchronizationContext/continueOnCapturedContext. ConfigureAwait(false) really
should have been the default. Otherwise, my experience with both seems about
equivalent.

