Linq.J 将 C# LINQ 的强大能力带入 Java 世界。通过优雅的链式 API,
像写 SQL 一样对 List、Array、Stream 等内存数据进行关联、筛选、排序和聚合。
var result = Linq.from(employees)
.innerJoin(departments, Dept::getId, Emp::getDeptId)
.where(Emp::getSalary, salary -> salary > 5000)
.groupBy(Dept::getName)
.select(
Columns.of(Dept::getName, "department"),
Columns.avg(Emp::getSalary, "avgSalary"),
Columns.count("headcount")
)
.orderByDesc(Emp::getSalary)
.write(DeptStats.class);
轻量、强大、优雅 — 用最少的代码完成最复杂的数据查询
运行时无任何第三方依赖,仅 50KB 大小。引入即用,不会给项目带来任何负担。
Select、Join、Where、Group By、Order By、Limit… 用你熟悉的 SQL 思维操作内存数据。
基于 Lambda 方法引用的列操作,编译期检查字段名,IDE 自动补全,告别魔法字符串。
List、Array、SQL 结果集、CSV/JSON/XML、Stream… 任何内存中的集合都能查询。
抽象 Engine 接口,默认 EruptEngine 内置 Hash Join 等高效策略,可自定义扩展。
COUNT、SUM、AVG、MAX、MIN、COUNT DISTINCT… 完整的聚合能力,配合 Group By 使用。
Linq.J 提供了与 SQL 一一对应的操作方法,链式调用一气呵成
leftJoin()
rightJoin()
innerJoin()
fullJoin()
eq()
like()
between()
in()
isNull()
gt() / lt()
where(λ)
select(Class)
select(Field...)
count()
sum()
avg()
max() / min()
write(Class)
writeOne(Class)
writeMap()
writeMapOne()
像写 SQL 一样操作 Java 对象,代码即文档
从简单的排序过滤到复合操作,一行代码搞定。支持原始类型和自定义对象。
// 字符串排序过滤
var strings = Linq.from("C", "A", "B", "B")
.gt(Th::is, "A")
.orderByDesc(Th::is)
.write(String.class);
// 结果: [C, B, B]
// 数字排序
var integers = Linq.from(1, 2, 3, 7, 6, 5)
.orderBy(Th::is)
.write(Integer.class);
// 结果: [1, 2, 3, 5, 6, 7]
支持四种标准 JOIN 操作,使用 Hash 策略实现高效关联,语法与 SQL 完全对应。
// Left Join + 多表 Select
Linq.from(source)
.leftJoin(target, Target::getId, Source::getId)
.select(Source.class)
.select(Target::getName)
.write(Result.class);
// Inner Join + Where + Distinct
var names = Linq.from(data)
.innerJoin(target, Target::getId, Data::getId)
.like(Data::getName, "a")
.select(Data::getName)
.distinct()
.orderBy(Data::getName)
.write(String.class);
从简单的等值比较到复杂的自定义条件,WHERE 子句覆盖你的所有需求。
// 精确匹配
Linq.from(source).eq(User::getName, "Thanos");
// 范围查询
Linq.from(source).between(User::getId, 1, 100);
// 自定义单字段条件
Linq.from(source).where(User::getId, id -> id >= 5);
// 多字段组合条件
Linq.from(source).where(row -> {
String name = row.get(User::getName);
Integer age = (Integer) row.get(User::getAge);
return "admin".equals(name) || age > 18;
});
Group By + 聚合函数 + Having,完整的分组聚合能力,生成统计报表轻而易举。
Linq.from(source)
.groupBy(Order::getCategory)
.select(
Columns.of(Order::getCategory, "name"),
Columns.min(Order::getDate, "earliest"),
Columns.avg(Order::getPrice, "avgPrice"),
Columns.count("total"),
Columns.countDistinct(
Order::getBuyer, "uniqueBuyers"
)
)
.having(row ->
Integer.parseInt(
row.get("total").toString()
) > 10
)
.orderBy(Order::getPrice)
.write(CategoryStats.class);
查询结果可以映射为 Java 对象、List、Map 或单个值,满足不同场景需求。
// 写出为对象列表
List<User> list = Linq.from(source)
.orderByAsc(User::getDate)
.write(User.class);
// 写出单个对象
User one = Linq.from(source)
.limit(1)
.writeOne(User.class);
// 写出为 Map 列表
List<Map<String, Object>> maps =
Linq.from(source).writeMap();
// 写出单个 Map
Map<String, Object> map =
Linq.from(source).writeMapOne();
查询构建与执行引擎解耦,接口隔离,灵活可扩展
分布式微服务、数据处理、报表生成… 无处不在
Feign / Dubbo / gRPC 等微服务调用返回的多个结果集,通过 Linq.J 在内存中进行 JOIN 关联,替代多次数据库查询。
Redis、MongoDB、MySQL 等不同数据源的结果,统一加载到内存后,用 Linq.J 进行跨源查询与聚合。
数据库查询结果需要进一步排序、过滤、聚合?Linq.J 让代码替代复杂的二次 SQL,逻辑清晰可维护。
多结果合并后的排序聚合与内存分页,告别手写 for 循环和 if 分支,代码量减少 80%。
语义化地完成对象转换与映射,代码即文档,团队协作更清晰敏捷。
不同系统、不同存储的数据,通过 Linq.J 在应用层实现联邦访问,无需数据迁移。
零配置,即装即用
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>linq.j</artifactId>
<version>LATEST</version>
</dependency>
@Getter // Lombok 注解
public class User {
private Long id;
private String name;
private Integer age;
}
List<User> adults = Linq.from(users)
.where(User::getAge, age -> age >= 18)
.select(User::getName, User::getAge)
.orderBy(User::getAge)
.write(User.class);
Map<String, List<Order>> grouped = new HashMap<>();
for (Order o : orders) {
if (o.getAmount() > 100) {
grouped.computeIfAbsent(
o.getCategory(),
k -> new ArrayList<>()
).add(o);
}
}
Map<String, Double> avgMap = new HashMap<>();
for (var entry : grouped.entrySet()) {
double sum = 0;
for (var o : entry.getValue()) {
sum += o.getAmount();
}
avgMap.put(entry.getKey(),
sum / entry.getValue().size());
}
// 还需要排序... 更多代码...
var result = Linq.from(orders)
.where(Order::getAmount,
a -> a > 100)
.groupBy(Order::getCategory)
.select(
Columns.of(
Order::getCategory, "cat"),
Columns.avg(
Order::getAmount, "avg"),
Columns.count("cnt")
)
.orderByDesc(Order::getAmount)
.write(Stats.class);
// 清晰 · 简洁 · 高效
Linq.J 正在不断完善,更多强大特性即将到来
分组聚合后的条件过滤
支持 group by date(created_at) 等表达式
UNION ALL、UNION、INTERSECT、EXCEPT、UNION BY NAME
ROW_NUMBER、RANK、DENSE_RANK 等分析函数