26

Started to learn LINQ with C#.
Especially LINQ to Objects and LINQ to XML.
I really enjoy the power of LINQ.

I learned that there is something called JLINQ a JavaScript implementation.
Also (as Catbert posted) Scala will have LINQ

Do you know if LINQ or something similar will be a part of Java 7?

Update: Interesting post from 2008 - LINQ for Java tool

Teejay
  • 7,210
  • 10
  • 45
  • 76
Kb.
  • 7,240
  • 13
  • 56
  • 75
  • I've always considered LINQ to be "ugly" and wrong. It looks deceptively powerful, and you can create some big spaghetti with it. After all ORM solutions are trying to minimize the use of SQL-like languages. Why re-introduce them? – Bozho Jan 05 '10 at 21:20
  • 28
    Bozho, LINQ is not purely about ORM, it is also, especially in the case of linq2objects and combined with lambda notation, a system to allow functional programming within C#. This is, for many people, the most useful feature of LINQ, not the ORM. – AlecZorab Jan 06 '10 at 11:39
  • @Bozho: Besides what AlecZorab said about the functional nature of LINQ, the problem with SQL-like languages is not their "SQLness" in itself, their problem has been they were typically implemented as string-based embedded languages. Whatever, the "SQLness" of LINQ is only a matter of syntax over set/relational operations; it could be map, zip, filter, project, etc. keywords instead of select, where, group by, etc, and LINQ functionality would be the same without looking like a SQL-like language. – Rafa Castaneda Feb 02 '10 at 20:56
  • 2
    Check this one: github.com/nicholas22/jpropel-light, real example:new String[] { "james", "john", "john", "eddie" }.where(startsWith("j")).toList().distinct(); – NT_ Oct 08 '11 at 10:19
  • I've also got I library I just published as version 0.9 called Linq-A-Like. As per Mr Sobral's answer its only answering bullet number 3, using Java's lambda's and the chaning nature of `Iterable` as bet it can to achieve number 1. You can get it on Maven central here: http://search.maven.org/#artifactdetails|com.empowerops|LinqALike|0.9.57.198|jar – Groostav Apr 19 '15 at 18:57

8 Answers8

33

Look at Scala, which is powerful functional programming language, but is similar to Java and runs on Java platform.

In Scala it is possible to use essentially the same code constructs as in LINQ, albeit without special query comprehensions syntax present in C# or VB.

EDIT :

Here's an example of Scala's querying capabilities :

// Get all StackOverflow users with more than 20,000 reputation points.
val topUsers = for{
    u <- users
    if u.reputation > 20000
} yield u;

println ("Users with more than 20,000 reputation:")
for (u <- topUsers) {
    println u.name
}
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
catbert
  • 1,017
  • 1
  • 9
  • 19
30

It's important to note that LINQ are four things:

  • Monadic comprehension
  • Database integration
  • SQL-like syntax
  • AST manipulation

People who just have heard of it may think of it simply as database integration. People who have worked a little with it probably think of SQL-like syntax. Those who really dug in will be aware of the monadic comprehension aspect of it, even if they don't know it for what it is.

If one takes Scala, for example, it has monadic comprehension without the other three. There is a library called ScalaQuery which provides database integration through the monadic comprehension (the intrinsic ability to do so being the main reason monads are cool). Another project, called ScalaQL, I think, intends to provide pretty much the same thing, but using a compiler plugin to enhance it. I wasn't aware of Miguel Garcia's work you mentioned, but, having seen other stuff he has accomplished, I'm thrilled by it.

One doesn't need special syntax to do monadic comprehension, however. It just makes it uncluttered by boilerplate. So that aspect of it is instantly available to languages with the right level of generics support.

Two things Scala doesn't do. The first is SQL-like syntax. That much can't be helped: SQL syntax looks out of place in Scala. I think it's safe to say most Scala programmers would prefer to stay with what is familiar to them -- the so-called for comprehensions.

The other thing is the one I haven't discussed yet, AST manipulation. That is the ability to manipulate code that has been parsed by the compiler, but not yet transformed in byte code, granting the ability to alter it before the generation is completed.

I think such a thing would be a boon to Scala -- heck, to any language. But, then again, I have a background as a Forth programmer, where the ability to alter code as it was being compiled was a God-given right. .Net can do it through LINQ, and so can some other languages, such as Ruby.

Kb.
  • 7,240
  • 13
  • 56
  • 75
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • @Daniel: +1 Thanks. Interesting. I am not sure wether .Net LINQ is able to do AST Manipulation. – Kb. Jan 06 '10 at 17:06
  • 2
    AST Manipulation is what Expressions Tree are about. See http://stackoverflow.com/questions/1430738/what-is-the-max-linq-expression-trees-can-do, for a bit more discussion. – Daniel C. Sobral Jan 06 '10 at 19:58
  • Scala can alter code. It's based on java. You can use objectweb ASM or AspectJ or Spring or some custom classloader. – KitsuneYMG Feb 15 '10 at 16:12
  • 1
    @kts That's irrelevant, and, besides, I never said Scala cannot alter code -- though using objectweb ASM, AspectJ or Spring would not classify as "Scala". Please, read the next to last paragraph again -- the ability I describe is not the ability to alter code that has been compiled, but alter what code is compiled into. – Daniel C. Sobral Feb 16 '10 at 07:52
13

LINQ would be hard in Java due to the current lack of closures. Assuming Java 7 really does get reasonably compact closure support and extension methods, LINQ in terms of "dot notation" should be feasible even if it doesn't get the equivalent of query expressions.

The Google Collections Library (now at 1.0 - but to be replaced by Guava when that is ready) contain many of the required methods - and I wouldn't be surprised to see 101 LINQ-like APIs spring up as soon as the closure support looks reasonably final.

I can't see (at the moment) Java getting anything like expression trees, however - so I suspect you'll be limited to LINQ to Objects unless you have custom compilation.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @Jon Skeet: Thanks +1. And Java closures are the same as LINQ enabling technology in .Net? – Kb. Jan 05 '10 at 18:38
  • 2
    @Kb: closures are also known as lambdas in C#, and they're the major feature supporting LINQ (extension methods are another, but they're less important). Expression trees are the force behind LINQ to SQL (and other similar stuff), but, like Jon said, those are not expected for Java 7. – R. Martinho Fernandes Jan 05 '10 at 18:47
  • Many Java Systems manipulate the byte code on load, rather than the AST during compilation, and the platform has many hooks to facilitate this. Expression trees are an implementation strategy, rather than a necessity. – Pete Kirkham Jan 30 '10 at 11:03
11

Check out Quaere. It's a LINQ-like DSL for Java that you can include as a library. Example:

// Get all StackOverflow users with more than 20,000 reputation points.
Iterable<User> topUsers = from("u").in(entityManager.entity(User.class)).
    where(gt("u.getReputation()", 20000)).
    select("u");

System.out.println("Users with more than 20,000 reputation:");
for (User u : topUsers) {
    System.out.println(u.getName());
}

However, note that Java doesn't have a concept analogous to extension methods. Whatever's in Quaere is pretty much what you're stuck with; if you need to make your own special utilities, they'll probably have to be in separate utility classes (ick).

Additionally, because Java < 7 has no native closures, you're stuck with strings to reference things, and your IDE can't introspect those to show you problems if you mistype something. (A smarter IDE might be able to handle this shortcoming, however, if somebody were to write introspection plugins for Quaere.)

John Feminella
  • 303,634
  • 46
  • 339
  • 357
11

By using the lambdaj library you can find the top reputation users as it follows:

List<User> topUsers = 
    select(users, having(on(User.class).getReputation(), greaterThan(20000)));

It has some advantages respect the Quaere library because it doesn't use any magic string, it is completely type safe and in my opinion it offers a more readable DSL.

Mario Fusco
  • 13,548
  • 3
  • 28
  • 37
4

You could try diting which implements chainable query methods on a collection.

   Integer[] values = new Integer[] {0,1,2,3,4,5,6,7,8,9,10};

   Enumerable<Integer> query = new Enumerable<Integer>(values).where(new Predicate<Integer>(){

    @Override
    public boolean evaluate(Integer value) throws Exception {
        return value % 2 == 0;
    }});

   for(Integer i : query)
   {
       System.out.write(i);
       System.out.write('\n');
   }
Anuj Balan
  • 7,629
  • 23
  • 58
  • 92
3

CQEngine or Collection Query Engine http://code.google.com/p/cqengine/ seems extremely promising. Haven't tried it though. It allows you to build indices over collections and query them. Supposed to be very quick.

Faheem Sohail
  • 806
  • 8
  • 21
2

Is there something as simple to use as LINQ-2-SQL on the JVM? I want to generate entities (classes) from the DB scheme using some tool and use those to interact directly with the DB. Is there an XML-free solution? I don't want to have to annotate the classes. In .NET, the tool is called sqlmetal. It's sort of a pre-processor that generates all the DB classes, so to speak.

Once this is done, I think it'll be fairly easy to use Scala's built in language constructs.

Mohamed Bana
  • 1,251
  • 2
  • 17
  • 27
  • Querydsl supports SQL as a backend. You can generate query types from an database schema. If you want a more standard based approach then consider generating an JPA compliant domain model from your schema and use Hibernate or some other JPA engine. Querydsl : http://source.mysema.com/display/querydsl/Querydsl – Timo Westkämper May 16 '10 at 12:47