Does Java 8 still need LINQ? Or is it better than LINQ?
Many people have tried to bring LINQ to Java. But can’t the Java community get along just fine without it?
Where is Java now?With the imminent release of Java 8 and JSR-355, do we still need LINQ? Many attempts of bringing LINQ goodness to Java have been made since the middle of the last decade. At the time, Quaere and Lambdaj seemed to be a promising implementation on the library level (not the language level). In fact, a huge amount of popular Stack Overflow questions hints at how many Java folks were (and still are!) actually looking for something equivalent:
- What is the Java equivalent for LINQ?
- LINQ for Java tool
- Is there something like LINQ for Java?
- What are the Java equivalents to Linq and Entity Framework?
But do we really need LINQ?LINQ has one major flaw, which is advertised as a feature, but in our opinion, will inevitably lead to the “next big impedance mismatch”. LINQ is inspired by SQL and this is not at all a good thing. LINQ is most popular for LINQ-to-Objects, which is a fine way of querying collections in .NET. The success ofHaskell or Scala, however, has shown that the true functional nature of “collection querying” tends to employ entirely other terms than
GROUP BY, or
HAVING. They use terms like “fold”, “map”, “flatMap”, “reduce”, and many many more. LINQ, on the other hand, employs a mixture of
GROUP BYand terms like “skip”, “take” (instead of
FETCH). In fact, nothing could be further from the functional truth than a good old SQLpartitioned outer join, grouping set, or framed window function. These constructs are mere declarations of what a SQL developer would like to see as a result. They’re not self-contained functions, which actually contain the logic to be executed in any given context. Moreover, window functions can be used only in
ORDER BYclauses, which is obvious when thinking in a declarative way, but which is also very weird if you don’t have the SQL context. Specifically, a window function in a
SELECTclause influences the whole execution plan and the way indexes are employed to pre-fetch the right data. Conversely, true functional programming can do so much more to in-memory collections than SQL ever can. Using a SQLesque API for collection querying was a cunning decision to trick “traditional” folks into adopting functional programming. But the hopes that collection and SQL table querying could be interfused were disappointed, as such constructs will not produce the wanted SQL execution plans. Conversely, true functional programming can do so much more to in-memory collections than SQL ever can. Using a SQLesque API for collection querying was just the wrong decision. The hopes that collection and SQL table querying could be interfused were disappointed, as such constructs will inevitably produce horrible SQL execution plans.
But what if I am doing SQL?It’s simple. When you do SQL, you have two essential choices.
- Do it “top-down”, putting most focus on your Java domain model. In that case, use Hibernate / JPA for querying and transform Hibernate results using the Java 8 Streams API.
- Do it “bottom-up”, putting most focus on your SQL / relational domain model. In that case, use JDBC or jOOQ and again, transform your results using the Java 8 Streams API.