17

Are there any libraries in Java that come close to providing the functionality of Linq?

rdasxy
  • 3,343
  • 7
  • 31
  • 41

7 Answers7

20

To get full LINQ query syntax, you would need an update to the language spec and compilers supporting the new keywords and syntax structure. This is far beyond most readers here.

In order to get Linq-like method-chain syntax in Java that looks and works like what's in C#, you need two things Java doesn't support; extension methods (static methods that can be applied to an instance as if it were an instance method), and lambda expressions (anonymous delegates). However, those two can be spoofed with existing Java constructs, if you're willing to incur a little extra coding verbosity. One thing I find particularly amazing about Java is the ability to create anonymous interface implementations; applied to an interface with a single pure function, that basically allows for simple anonymous delegates, provided you have an interface for each method signature you'll need.

So, the IEnumerable (Iterable for the Javaheads) side of Linq, as a method chain, should be possible to approximate in Java; you'd basically implement it as a fluent interface that controls a monad. You'd need a class like a LinqIterable, implementing Iterable, that:

  • can convert any Iterable input into a LinqIterable instance
  • has methods for basic list processing, such as filtering, grouping, concatenation, intersection, ordering, etc that accept single-function interfaces and produce new LinqIterables, allowing chaining of these methods, hopefully in a "lazy" fashion.
  • has methods to transform the LinqIterable back into "concrete" objects such as ToList, ToArray, ToMap, etc

So, you could probably define a "fluent" library that would allow a statement such as:

Map<String, Integer> results = Linq.FromIterable(sourceList)
                           .Where(new Predicate{public bool Op(SomeStruct in){return in.SomeString == "criteria";}})
                           .OrderBy(new Func{public String Op(SomeStruct in){return in.SomeOtherString;}})
                           .Select(new Func{public SomeOtherStruct Op(SomeStruct in){return new SomeOtherStruct(in.SomeOtherString, in.SomeInt);}})
                           .ToMap(new Func{public String Op(SomeOtherStruct in){return in.StringField;}},
                                  new Func{public Integer Op(SomeOtherStruct in){return in.IntField;}});

Creation of the actual library is an exercise far beyond the scope of an answer on an internet Q&A. I just said it was possible, not easy.

Expression trees are not rocket science, but it would be a significant project to implement what .NET has in this area; not only do you need the ability to build an expression tree, you need to be able to "compile" this tree on the fly using emitted bytecodes; I don't know if Java's reflection is quite that powerful.

KeithS
  • 22,282
8

See:

5

No. Linq requires lots of langage features that Java just dosent have

Tom Squires
  • 17,835
3

Use Scala, for the reasons explained here:

use the .NET port of Scala. It gives you full native access to everything in .NET, which obviously includes LINQ.

If you can't, you can try to use libs like functionjava or lambdaj, but you won't come really close to LINQ.

Landei
  • 1,993
  • 1
  • 13
  • 19
2

I'd add guava to the list of libraries that may help you achieve some of the things LINQ does.

But as others have pointed out, there is no equivalent in pure Java.

2

There isn't a native feature in java that mimics linq. However, there are several APIs that provide the same functionality.

For example, this blog post has a custom jar to replicate linq.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

And this is an example usage of the API from the post:

Suppose we have an Animal object containing name and ID which is represented with a list of animals. If we want to get the all the Animal names which contains 'o' from the list animals, we can write the following query

from(animals).where("getName", contains("o")).all();

There are two other APIs referenced in the blog posting: lambdaJ and jLinq

vishnu
  • 21
2

You could use Korma, a DSL for SQL queries written in Clojure.

Syntax is pretty neat:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

You can call this pretty easily from Java by importing the relevant Clojure libraries and just using the normal Clojure/Java interop.

mikera
  • 20,777