Translate

miércoles, 10 de junio de 2026

Java Streams vs LINQ


A simple vista, Java y C# parecen ofrecer lo mismo:


users.stream()

     .filter(u -> u.getAge() > 50)

     .toList();


users.Where(u => u.Age > 50).ToList();


  • Sintaxis similar
  • Misma intención


Pero internamente… son dos mundos completamente distintos.

  • En Java, una lambda es código ejecutable
  • En LINQ, puede ser datos (un AST)


Y eso cambia todo.


En Java, esto:

Predicate<User> p = u -> u.getAge() > 50;


Se compila a bytecode usando invokedynamic

Es equivalente a:


class Lambda implements Predicate<User> {

    public boolean test(User u) {

        return u.getAge() > 50;

    }

}


No hay forma de saber:

  • qué propiedad se accede (age)
  • qué operador se usa (>)
  • qué constante (50)

Solo podés ejecutarla, no analizarla

Por lo tanto, siempre ocurre en memoria. Nunca puede transformarse en sql o en nada


En .NET LINQ, esto:

users.Where(u => u.Age > 50)


Puede ser interpretado como:

Expression<Func<User, bool>>


Esto NO es una función

Es un árbol de expresión (AST)


¿Cómo se ve ese AST?

Conceptualmente:

GreaterThan

 ├── MemberAccess (Age)

 └── Constant (50)


O en código:

BinaryExpression(

    left: MemberExpression("Age"),

    operator: GreaterThan,

    right: Constant(50)

)


Ahora sí podés:

  • traducir a SQL
  • optimizar
  • serializar
  • ejecutar en distintos motores


¿Por qué Java eligió este camino?

Java priorizó:

  • simplicidad
  • performance
  • compatibilidad


Las lambdas fueron diseñadas como:  “syntactic sugar” sobre interfaces funcionales

No como estructuras analizables.


 ¿Se podría implementar LINQ en Java?

Sí… pero requeriría:

  • lambdas introspectables
  • un AST estándar en el lenguaje
  • cambios en el compilador


Streams y LINQ no son equivalentes.

  • Streams son pipelines de ejecución
  • LINQ es un lenguaje de queries embebido

No hay comentarios.:

Publicar un comentario