Java进阶-JINQ详解与使用

本文详细介绍了JINQ(Java Integrated Query),一种强化Java中数据查询能力的库,提供类SQL的查询语法和类型安全的操作。文章首先解释了JINQ的基本功能和应用,随后通过具体示例展示了如何使用JINQ进行数据过滤、投影、连接、分组等操作。接着,与Java Stream API、Google Guava等其他热门集合处理包进行了比较,突出了JINQ在类型安全和查询直观性方面的优势。最后,总结了JINQ的使用价值,特别是对于需要进行复杂数据处理的Java开发者。
在这里插入图片描述


一、JINQ介绍

1. JINQ简述

JINQ(Java Integrated Query)是一个为Java设计的库,类似于C#的LINQ,它提供了一个强大的查询接口,允许开发者以声明式方式处理Java集合和数据库查询。JINQ利用Java 8的lambda表达式和Stream API,使得数据库和集合的查询更加直观和类型安全。

2. JINQ支持的功能

功能描述
查询转换允许对数据库或集合进行转换查询,如映射、筛选等
聚合操作支持对数据进行聚合操作,如计数、求和、平均值等
类型安全的查询通过API保证查询的类型安全,减少运行时错误
集成数据库查询可以直接在数据库上执行类似LINQ的查询,而不仅限于内存中的集合
延迟执行查询操作是延迟执行的,只有在需要结果时才进行计算

3. JINQ的使用优势

特性 / 工具JINQJava Stream APISQL
查询能力针对数据库和Java集合仅限Java集合仅限数据库
类型安全否(依赖字符串查询)
延迟执行通常不是(即时查询)
聚合操作强大,支持多种数据库操作有限,主要是内存中处理强大,直接在数据库执行
使用难度中等,需要理解查询表达式较低,易于上手高,需要SQL知识

二、常用的JINQ功能

1. Where 过滤

通过where方法,可以实现对数据集的条件过滤,仅返回满足条件的元素集合。

List<Product> allProducts = Arrays.asList(new Product("TV", "Electronics"), new Product("Blender", "Kitchen"));
List<Product> electronics = jinqStream.where(p -> p.getCategory().equals("Electronics")).toList();
System.out.println(electronics); // 输出: [Product{name='TV', category='Electronics'}]

2. Select 投影

使用select方法可以选择数据流中的特定字段,类似于SQL中的SELECT子句。

List<String> productNames = jinqStream.select(Product::getName).toList();
System.out.println(productNames); // 输出: ["TV", "Blender"]

3. Join 连接

join方法允许对两个相关的数据集进行关联,实现内连接或外连接。

List<Product> products = Arrays.asList(new Product("TV", 1), new Product("Blender", 2));
List<Supplier> suppliers = Arrays.asList(new Supplier(1, "Sony"), new Supplier(2, "Samsung"));
List<Pair<Product, Supplier>> productsWithSuppliers = jinqStream.join(Product::getSupplierId, Supplier::getId).select(pair -> new Pair<>(pair.getOne(), pair.getTwo())).toList();
System.out.println(productsWithSuppliers); // 输出: [Pair{one=Product{name='TV', supplierId=1}, two=Supplier{id=1, name='Sony'}}, Pair{one=Product{name='Blender', supplierId=2}, two=Supplier{id=2, name='Samsung'}}]

4. GroupBy 分组

groupBy方法允许将数据按照指定的属性分组,类似于SQL中的GROUP BY子句。

List<Product> products = Arrays.asList(new Product("TV", "Electronics"), new Product("Blender", "Kitchen"), new Product("Microwave", "Kitchen"));
Map<String, List<Product>> productsByCategory = jinqStream.groupBy(Product::getCategory).toList();
System.out.println(productsByCategory); // 输出: {'Electronics': [Product{name='TV', category='Electronics'}], 'Kitchen': [Product{name='Blender', category='Kitchen'}, Product{name='Microwave', category='Kitchen'}]}

5. OrderBy排序

orderBy方法允许对结果集进行排序,支持升序或降序。

List<Product> products = Arrays.asList(new Product("TV", 500), new Product("Blender", 150), new Product("Microwave", 200));
List<Product> sortedProducts = jinqStream.orderBy(Comparator.comparing(Product::getPrice)).toList();
System.out.println(sortedProducts); // 输出: [Product{name='Blender', price=150}, Product{name='Microwave', price=200}, Product{name='TV', price=500}]

6. Aggregate聚合

aggregate方法用于执行各种聚合操作,如求和、求平均、最大值和最小值等。

List<Product> products = Arrays.asList(new Product("TV", 500), new Product("Blender", 150), new Product("Microwave", 200));
BigDecimal totalRevenue = jinqStream.aggregate(sum(Product::getPrice), BigDecimal.ZERO);
System.out.println(totalRevenue); // 输出: 850 (假设价格单位为元)

7. Count计数

使用count方法可以快速计算满足特定条件的元素数量。

List<Product> products = Arrays.asList(new Product("TV", 500), new Product("Blender", 150), new Product("Microwave", 200));
long expensiveProductsCount = jinqStream.where(p -> p.getPrice() > 300).count();
System.out.println(expensiveProductsCount); // 输出: 1

8. Distinct去重

distinct方法用于去除重复元素,确保结果集中的每个元素都是唯一的。

List<String> categories = Arrays.asList("Electronics", "Kitchen", "Electronics", "Kitchen");
List<String> uniqueCategories = jinqStream.distinct().toList();
System.out.println(uniqueCategories); // 输出: ["Electronics", "Kitchen"]

9. Limit限制

使用limit方法可以限制结果集的大小,类似于SQL中的LIMIT子句。

List<Product> products = Arrays.asList(new Product("TV", 500), new Product("Blender", 150), new Product("Microwave", 200));
List<Product> limitedProducts = jinqStream.limit(2).toList();
System.out.println(limitedProducts); // 输出: [Product{name='TV', price=500}, Product{name='Blender', price=150}]

10. Skip跳过

skip方法允许跳过结果集中的前N个元素,继续处理之后的元素。

List<Product> products = Arrays.asList(new Product("TV", 500), new Product("Blender", 150), new Product("Microwave", 200));
List<Product> remainingProducts = jinqStream.skip(1).toList();
System.out.println(remainingProducts); // 输出: [Product{name='Blender', price=150}, Product{name='Microwave', price=200}]

三、JINQ和类似包的比较

1. 常见的Java集合处理库

在Java中处理集合和数据流时,除了JINQ,还有多种流行的库提供了丰富的功能。
比如下面这些常用的Java集合处理包:

  • Java Stream API - Java 8及以上版本内置的功能,支持丰富的流操作。
  • Google Guava - 提供了多种强大的集合工具和扩展。
  • Apache Commons Collections - 提供了大量扩展集合操作的工具。
  • Eclipse Collections - 专注于性能和内存优化的丰富集合库。
  • Vavr(之前称为Javaslang)- 提供不可变集合和函数式编程工具,增强了Java的函数式编程能力。

2. 集合处理库之间的比较

每个包都有各自的特点和用途:

特性 / 库JINQJava Stream APIGoogle GuavaApache Commons CollectionsEclipse CollectionsVavr
主要优势类SQL查询语法,类型安全内置支持,流式处理丰富的集合工具和实用程序扩展旧Java版本的集合操作性能和内存优化不可变集合,函数式编程
数据处理模式同步同步或异步(并行流)同步同步同步或异步(并行集合)同步
类型安全
不可变集合全部不可变
函数式编程支持
专注领域数据库和集合查询集合流操作集合扩展和实用工具集合操作扩展集合性能优化集合和函数式编程
与Java版本兼容性Java 8+Java 8+Java 6+Java 1.2+Java 5+Java 8+

不同的库各有侧重点,例如Java Stream API适合进行复杂的流式数据处理,Google Guava提供了丰富的集合处理工具,Eclipse Collections关注于性能优化,而Vavr增强了Java的函数式编程能力。选择哪个工具库,取决于具体项目的需求和开发团队的熟悉度。


四、JINQ使用总结

JINQ为Java开发者提供了一个强大的工具,以声明式和类型安全的方式处理数据查询。它填补了Java Stream API在数据库查询方面的空白,并提供了一个高效的方式来处理集合和数据库中的数据。虽然它的学习曲线可能略高于直接使用Stream API,但它在数据查询和处理的能力上提供了显著的优势,特别是在需要与数据库交互的应用中。通过使用JINQ,开发者可以更加专注于业务逻辑,而不是数据访问代码的细节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/318616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【竞技宝】意甲:退出齐尔克泽争夺战!国米免签伊朗神锋!

博洛尼亚中锋齐尔克泽成为了意甲当红炸子鸡,不少豪门球队都希望可以签下他,目前对球员有意向的俱乐部包括AC米兰、尤文图斯、阿森纳、国际米兰和曼联,看到自家球员如此有市场,博洛尼亚方面咬死5000万欧元的价格不松口,想要得到他必须要拿出真金白银。不过意甲霸主国际米兰率先退…

408数据结构-二叉树的概念、性质与存储结构 自学知识点整理

前置知识&#xff1a;树的基本概念与性质 二叉树的定义 二叉树是一种特殊的树形结构&#xff0c;其特点是每个结点至多只有两棵子树&#xff08;即二叉树中不存在度大于 2 2 2的结点&#xff09;&#xff0c;并且二叉树是有序树&#xff0c;左右子树不能互换。 与树类似&#…

笔试强训week3

day1 Q1 难度⭐ 牛牛冲钻五_牛客小白月赛38 (nowcoder.com) 题目&#xff1a; 牛牛最近在玩炉石传说&#xff0c;这是一款一对一对战的卡牌游戏&#xff0c;牛牛打算努力冲上钻五分段&#xff0c;获得丰厚的天梯奖励。 炉石传说的段位可以用星数来表示&#xff0c;具体规则…

【linuxC语言】空洞文件

文章目录 前言一、空洞文件1.1 空洞文件的介绍1.2 用途 二、示例代码总结 前言 在 Linux 系统编程中&#xff0c;空洞文件是一种特殊类型的文件&#xff0c;它包含了逻辑上的空洞&#xff0c;也就是说文件中的某些部分并没有实际写入数据。尽管文件在逻辑上可能非常大&#xf…

webpack 常用插件

clean-webpack-plugin 这个插件的主要作用是清除构建目录中的旧文件&#xff0c;以确保每次构建时都能得到一个干净的环境。 var { CleanWebpackPlugin } require("clean-webpack-plugin") const path require("path");module.exports {mode: "de…

Springboot+mybatis升级版(Postman测试)

一、项目结构 1.导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apach…

12_Scala_package

文章目录 Scaal面向对象编程1.回顾Java2.package可以多次声明3.设置作用域&#xff0c;设置上下级4.包可以当作对象使用5.import6.Scala用_取代Java *7.导入多个包8.屏蔽类9.类起别名10.import的规则11.有些包无需导入 Scaal面向对象编程 Scala是一门完全面向对象语言&#xf…

Linux的权限管理

文章目录 文件权限文件类型文件访问者的分类文件权限的类型 文件访问权限的设置目录的权限 文件权限 对于每个LInux文件&#xff0c;如果用ll指令查看的话&#xff0c;可以发现每个文件前面都有一串类似的字符&#xff1a; 这里总共有十个字符&#xff0c;其中第一个字符表示…

QT httpServer多线程后台服务器的例子实现

1.需求 1.1 用户需要其他平台&#xff08;web端&#xff09;调用Qt平台的接口&#xff0c;获取想要的数据并实时显示在网页里&#xff0c;比如实时的温湿度&#xff0c;用户数据等 1.2 用户需要在其他平台&#xff08;web端&#xff09;调用Qt平台的接口&#xff0c;下发数据…

贝叶斯统计实战:Python引领的现代数据分析之旅

贝叶斯统计这个名字取自长老会牧师兼业余数学家托马斯贝叶斯(Thomas Bayes&#xff0c;1702—1761)&#xff0c;他最先推导出了贝叶斯定理&#xff0c;该定理于其逝世后的1763年发表。但真正开发贝叶斯方法的第一人是Pierre-Simon Laplace(1749—1827)&#xff0c;因此将其称为…

Copilot Venture Studio創始合伙人楊林苑確認出席“邊緣智能2024 - AI開發者峰會”

隨著AI技術的迅猛發展&#xff0c;全球正逐步進入邊緣計算智能化與分布式AI深度融合的新時代&#xff0c;共同書寫著分布式智能創新應用的壯麗篇章。邊緣智能&#xff0c;作為融合邊緣計算和智能技術的新興領域&#xff0c;正逐漸成為推動AI發展的關鍵力量。借助分布式和去中心…

Messari 报告摘要 :Covalent Network(CQT)2024 年第一季度表现

摘要&#xff1a; 尽管 CQT 代币流通供应量增加了 20%&#xff08;新增 1.04 亿枚 CQT&#xff09;&#xff0c;但 CQT 的质押百分比仅从 2023 年第一季度的 22% 增长到了 2024 年第一季度的 29%。 CQT 的市值季度环比增长了 28%&#xff0c;多次达到 2.75 亿美元&#xff0c…

分享三款可以给pdf做批注的软件

PDF文件不像Word一样可以直接编辑更改&#xff0c;想要在PDF文件上进行编辑批注需要用到一些专业的软件&#xff0c;我自己常用的有三款&#xff0c;全都是官方专业正版的软件&#xff0c;功能丰富强大&#xff0c;使用起来非常方便&#xff01; 1.edge浏览器 这个浏览器不仅可…

van-cascader(vant2)异步加载的bug

问题描述&#xff1a;由于一次性返回所有的级联数据的话&#xff0c;数据量太大&#xff0c;接口响应时间太久&#xff0c;因此采用了异步加载的方案&#xff0c;看了vant的官方示例代码&#xff0c;照着改了下&#xff0c;很轻松地实现了功能。正当我感叹世界如此美好的时候&a…

2.2 Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3-基础-Vue基本语法

文本渲染指令 文本渲染指令-v-html与v-text Vue使用了基于HTML的模板语法&#xff0c;允许开发者声明式地将DOM绑定至底层Vue实例的数据。所有Vue的模板都是 合法的HTML&#xff0c;所以能被遵循规范的浏览器和HTML解析器解析。 在前面&#xff0c;我们一直使用的是字符串插…

Flutter - 折叠面板

demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新&#xff0c;请前往github查看最新代码 flutter 自定义折叠组件 支持三种类型和两种展示效果可自定义title和被折叠的内容 效果图 示例 import package:flutter/material.dart; import /jh_common/widge…

springboot+websocket开发简单的在线群聊聊天web版本

springbootwebsocket开发简单的在线群聊聊天web版本&#xff01;近期在测试websocket插件的群聊功能。下面是一个简单的demo。分享给大家&#xff0c;亲测可以使用的。 1&#xff1a;首先是一个chat.html页面。代码如下&#xff1a; <!DOCTYPE html> <html lang"…

Linux的Shell脚本详解

本文目录 一、什么是 Shell 脚本文件 &#xff1f;二、编写Shell脚本1. 基本规则2. shell 变量&#xff08;1&#xff09;创建变量&#xff08;2&#xff09;引用变量&#xff08;3&#xff09;删除变量&#xff08;4&#xff09;从键盘读取变量&#xff08;5&#xff09;特殊变…

VMware安装ubuntun虚拟机使用桥接模式无法上网问题解决

问题&#xff1a;最近准备使用VMware虚拟机搭建k8s集群服务&#xff0c;因为需要在同一个网段下&#xff0c;我使用桥接的方式&#xff0c;我发现主机在使用有线连接时虚拟机网络连接正常&#xff0c;但是使用无线网就显示连接不上网络。 解决方法 一、查看网络连接&#xff…

MFC 列表控件删除实例(源码下载)

1、本程序基于前期我的博客文章《MFC下拉菜单打钩图标存取实例&#xff08;源码下载) 》 2、程序功能选中列表控件某一项&#xff0c;删除按钮由禁止变为可用&#xff0c;点击删除按钮&#xff0c;选中的项将删除。 3、首先在主界面添加一个删除参数按钮。 4、在myDlg.cpp 文件…