🙏废话不多说系列,直接开整🙏
【提示】:这种框架本质是 将程序SQL语句用法衍生到 开发语言JAVA 中的一个实践。可以按照 SQL 的思维去学习这种类型的框架(比如还有:JDFrame 等)
一、简单介绍
- 官方GitHub文档:GitHub - timandy/linq: LINQ to Objects for Java.
- 官方 gitee 地址:linq: LINQ to Objects for Java. (gitee.com)
术语“LINQ to Objects”指直接将 LINQ 查询与任何 IEnumerable<T>
集合一起使用。 可以使用 LINQ 来查询任何可枚举的集合,例如 Primitive Array
、Object Array
、 List
、 Collection
或 Iterable
等等。 该集合可以是用户定义的集合,也可以是由 Java 开发包 API 返回的集合。
从根本上说,“LINQ to Objects”表示一种新的处理集合的方法。 采用旧方法,必须编写指定如何从集合检索数据的复杂的 foreach
循环。 而采用 LINQ 方法,只需编写描述要检索的内容的声明性代码。
此外,LINQ 查询与传统 foreach
循环相比具有两大优势:
- 它们更简明、更易读,尤其在筛选多个条件时。
- 它们使用最少的应用程序代码提供强大的筛选、排序和分组功能。
LINQ 查询与 Stream API 相比也具有一定优势:
- 支持
foreach
循环,因此你可以随时中断循环。 - 可以重复遍历 IEnumerable 接口对象。
- LINQ 非常易于使用,如
ToCollection
、LeftJoin
等。 - 在大多数复杂情况下,LINQ 比 Stream API 更快。
通常,对数据执行的操作越复杂,就越能体会到 LINQ 相较于传统迭代技术的优势。
(1)特性
- 实现了 LINQ to Objects 的所有 API。
- 支持更多 API 和元组。
- 支持 IEnumerable 和 Stream 互相转换。
- 支持 Android。
(2)LINQ 的 API
- empty
- singleton
- ofNullable
- of
- as
- chars
- words
- lines
- split
- infinite
- loop
- enumerate
- iterate
- range
- repeat
(3)IEnumerable 的 API
forEach
stream
parallelStream
- aggregate
- all
- any
- append
- asEnumerable
- average
- cast
- chunk
- concat
- contains
- count
crossJoin
- defaultIfEmpty
- distinct
distinctBy
- elementAt
- elementAtOrDefault
- except
exceptBy
findIndex
findLastIndex
- first
- firstOrDefault
format
fullJoin
- groupBy
- groupJoin
indexOf
- intersect
intersectBy
- join
joining
- last
lastIndexOf
- lastOrDefault
leftJoin
- longCount
- max
maxBy
- min
minBy
- ofType
- orderBy
- orderByDescending
- prepend
- reverse
rightJoin
runOnce
- select
- selectMany
- sequenceEqual
shuffle
- single
- singleOrDefault
- skip
- skipLast
- skipWhile
- sum
- take
- takeLast
- takeWhile
- toArray
toCollection
toEnumeration
toLinkedList
toLinkedMap
toLinkedSet
- toList
- toLookup
- toMap
- toSet
- union
unionBy
- where
- zip
(4)IGrouping(继承 IEnumerable) 的 API
- getKey
(5)ILookup(继承 IEnumerable) 的 API
- getCount
- get
- containsKey
(6)IOrderedEnumerable(继承 IEnumerable) 的 API
- thenBy
- thenByDescending
(7)Index 的 API
- fromStart
- fromEnd
- getValue
- isFromEnd
- getOffset
(8)Range 的 API
- startAt
- endAt
- getStart
- getEnd
- getOffsetAndLength
(9)元组类
- Tuple1
- Tuple2
- Tuple3
- Tuple4
- Tuple5
- Tuple6
- Tuple7
- TupleN
(10)调试视图 (IntelliJ IDEA)
- 打开设置对话框
File | Settings | Build, Execution, Deployment | Debugger | Data Views | Java Type Renderers
。 - 单击
Add
按钮。 - 在
Renderer name
输入IterableView
。 - 在
Apply renderer to objects of type (fully-qualified name):
输入java.lang.Iterable
。 - 在
When rendering a node
小节,选中Use following expression:
并输入DebugView.getDebuggerDisplayText(this)
。 如果报错,按下Alt + Enter
导入类。 - 选中
Use list of expression:
并在Name
列输入**RESULT VIEW**
。 在Expression
列输入DebugView.getDebuggerProxyObject(this)
。 如果报错,按下Alt + Enter
导入类。 建议选中On-demand
,以便在必要时枚举序列。 - 如果你想查看
Iterable
实例的默认字段,选中Append default children
。 - 保存设置,尝试一下吧!
由于可能的副作用,应谨慎使用结果视图。
二、开始使用
(1)引入 Maven
或者 Gradle
<dependency>
<groupId>com.bestvike</groupId>
<artifactId>linq</artifactId>
<version>6.0.0</version>
</dependency>
Gradle 用法:
implementation 'com.bestvike:linq:6.0.0'
(2)官方测试部分样例
- 拼接不为空的字符串
- 判断所有的正数是否全部为偶数;
- 判断所有的正数是否存在任一偶数;
- 在末尾追加一个数字并在头部插入两个数字;
- 计算整数序列的平均值;
- 连接两个整数序列;
@Test
void basicApiTest1() {
// 拼接不为空的字符串
var result = Linq.of("!@#$%^", "C", "AAA", "", "Calling Twice", "SoS", Empty)
.where(x -> x != null && !x.isEmpty())
.aggregate((x, y) -> x + ", " + y);
System.out.println("拼接不为空的字符串为:" + result);// !@#$%^, C, AAA, Calling Twice, SoS
// 判断所有的正数是否全部为偶数。
boolean resultBoolean = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345)
.where(x -> x > 0)
.all(x -> x % 2 == 0);
System.out.println("判断所有的正数是否全部为偶数:" + resultBoolean);// false
// 判断所有的正数是否存在任一偶数。
boolean resultBoolean2 = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345)
.where(x -> x > 0)
.any(x -> x % 2 == 0);
System.out.println("判断所有的正数是否存在任一偶数: " + resultBoolean2);// true
// 在末尾追加一个数字并在头部插入两个数字
String result3 = Linq.range(3, 2).append(5).prepend(2).prepend(1).format();
System.out.println("在末尾追加一个数字并在头部插入两个数字: " + result3);// [1, 2, 3, 4, 5]
// 计算整数序列的平均值。
// 如果源数据为int则使用 averageInt()
double result4 = Linq.of(5, -10, 15, 40, 28).averageInt(); //15.6
// [注意-要求所有的数据按照统一类型数据表示]如果源数据为double则使用 averageDouble()
var result5 = Linq.of(5.6D, -12.0, 15D, 40D, 28D).averageDouble();// 15.319999999999999
System.out.println("平均值:" + result4 + " " + result5);// 平均值:15.6 15.319999999999999
// 连接两个整数序列。
String str = Linq.of(1, 2).concat(Linq.of(5, 6)).concat(Linq.of(9, 10)).format();
System.out.println("连接两个整数序列:" + str);// [1, 2, 5, 6, 9, 10]
List<String> s1 = Arrays.asList("one", "two");
String string = Linq.of(s1).concat(Linq.of(s1)).format(Formatter.DEFAULT);
System.out.println(string);
}
(2)自测 Linq
的 部分API
- 初始化数据,切分字符串;
- 集合统计值(最大值,最小值,平均值,总和,数量);
- 集合切分成多个子集合;
- ……
@Test
void basicApiDemo() {
// 1.Linq:切分字符串 直接转数组
//Linq.split("1,2,3", ",").cast(Long.class).forEach(System.out::println);
// 2.JDK8:
Arrays.stream("1,2,3".split(",")).mapToInt(Integer::parseInt).forEach(System.out::println);
// 2.1 linq: empty
List<String> emptyList = new ArrayList<>();
List<String> strings = Linq.of(emptyList).defaultIfEmpty(String.valueOf(Linq.split("0,0,0", ","))).stream().toList();
System.out.println("空集合则默认集合得到数据:" + strings);
List<Integer> intList = Linq.of(new int[]{10, 2, 2, 1, 3, 1, 5, 6, 7, 8}).toList();
int count = Linq.of(intList).count();
Integer max = Linq.of(intList).max();
int min = Linq.of(intList).min();
double averageInt = Linq.of(intList).averageInt();
int sumInt = Linq.of(intList).sumInt();
System.out.println("数量:" + count + " 最大值:" + max + " 最小值:" + min + " 平均值:" + averageInt + " 总和:" + sumInt);
List<String> strIntList = intList.stream().map(String::valueOf).toList();
System.out.println("JDK 数字集合转字符集合:" + JSONUtil.toJsonStr(strIntList));
System.out.println("分组:将集合按照2个元素分组划分");
List<Integer[]> list = Linq.of(intList).chunk(4, Integer.class).toList();
list.forEach(integers -> System.out.println(JSONUtil.toJsonStr(integers)));
// 集合去重 + 倒序输出
List<Integer> distinctIntList = Linq.of(intList).stream().sorted().distinct().toList();
distinctIntList = Linq.of(distinctIntList).reverse().toList();
System.out.println(JSONUtil.toJsonStr(distinctIntList));
//List<String> intStrList = Linq.of(intList).cast(String.class).toList();
//intStrList.forEach(System.out::println);
}
(4)🙏 献上:完整亲测代码 🌟
【1】完整代码
import cn.hutool.json.JSONUtil;
import com.bestvike.Index;
import com.bestvike.linq.Linq;
import com.bestvike.linq.util.Formatter;
import lombok.Builder;
import lombok.Data;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.bestvike.linq.util.Strings.Empty;
@SpringBootTest
class LinqTests {
@Test
void contextLoads() {
}
@Test
void basicApiDemo() {
// 1.Linq:切分字符串 直接转数组
//Linq.split("1,2,3", ",").cast(Long.class).forEach(System.out::println);
// 2.JDK8:
Arrays.stream("1,2,3".split(",")).mapToInt(Integer::parseInt).forEach(System.out::println);
// 2.1 linq: empty
List<String> emptyList = new ArrayList<>();
List<String> strings = Linq.of(emptyList).defaultIfEmpty(String.valueOf(Linq.split("0,0,0", ","))).stream().toList();
System.out.println("空集合则默认集合得到数据:" + strings);
List<Integer> intList = Linq.of(new int[]{10, 2, 2, 1, 3, 1, 5, 6, 7, 8}).toList();
int count = Linq.of(intList).count();
Integer max = Linq.of(intList).max();
int min = Linq.of(intList).min();
double averageInt = Linq.of(intList).averageInt();
int sumInt = Linq.of(intList).sumInt();
System.out.println("数量:" + count + " 最大值:" + max + " 最小值:" + min + " 平均值:" + averageInt + " 总和:" + sumInt);
List<String> strIntList = intList.stream().map(String::valueOf).toList();
System.out.println("JDK 数字集合转字符集合:" + JSONUtil.toJsonStr(strIntList));
System.out.println("分组:将集合按照2个元素分组划分");
List<Integer[]> list = Linq.of(intList).chunk(4, Integer.class).toList();
list.forEach(integers -> System.out.println(JSONUtil.toJsonStr(integers)));
// 集合去重 + 倒序输出
List<Integer> distinctIntList = Linq.of(intList).stream().sorted().distinct().toList();
distinctIntList = Linq.of(distinctIntList).reverse().toList();
System.out.println(JSONUtil.toJsonStr(distinctIntList));
//List<String> intStrList = Linq.of(intList).cast(String.class).toList();
//intStrList.forEach(System.out::println);
}
@Test
void basicApiTest1() {
// 拼接不为空的字符串
var result = Linq.of("!@#$%^", "C", "AAA", "", "Calling Twice", "SoS", Empty)
.where(x -> x != null && !x.isEmpty())
.aggregate((x, y) -> x + ", " + y);
System.out.println("拼接不为空的字符串为:" + result);// !@#$%^, C, AAA, Calling Twice, SoS
// 判断所有的正数是否全部为偶数。
boolean resultBoolean = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345)
.where(x -> x > 0)
.all(x -> x % 2 == 0);
System.out.println("判断所有的正数是否全部为偶数:" + resultBoolean);// false
// 判断所有的正数是否存在任一偶数。
boolean resultBoolean2 = Linq.of(9999, 0, 888, -1, 66, -777, 1, 2, -12345)
.where(x -> x > 0)
.any(x -> x % 2 == 0);
System.out.println("判断所有的正数是否存在任一偶数: " + resultBoolean2);// true
// 在末尾追加一个数字并在头部插入两个数字
String result3 = Linq.range(3, 2).append(5).prepend(2).prepend(1).format();
System.out.println("在末尾追加一个数字并在头部插入两个数字: " + result3);// [1, 2, 3, 4, 5]
// 计算整数序列的平均值。
// 如果源数据为int则使用 averageInt()
double result4 = Linq.of(5, -10, 15, 40, 28).averageInt(); //15.6
// [注意-要求所有的数据按照统一类型数据表示]如果源数据为double则使用 averageDouble()
var result5 = Linq.of(5.6D, -12.0, 15D, 40D, 28D).averageDouble();// 15.319999999999999
System.out.println("平均值:" + result4 + " " + result5);// 平均值:15.6 15.319999999999999
// 连接两个整数序列。
String str = Linq.of(1, 2).concat(Linq.of(5, 6)).concat(Linq.of(9, 10)).format();
System.out.println("连接两个整数序列:" + str);// [1, 2, 5, 6, 9, 10]
List<String> s1 = Arrays.asList("one", "two");
String string = Linq.of(s1).concat(Linq.of(s1)).format(Formatter.DEFAULT);
System.out.println(string);
}
@Test
void updateAddress() {
System.out.println(Index.fromStart(2));
System.out.println(Linq.lines("HELLO WORLD").reverse().toList());
}
private static List<User> users = new ArrayList<>();
private static List<Dept> depts = new ArrayList<>();
private static List<UserDept> userDepts = new ArrayList<>();
static {
// 用户数据初始化
users.add(User.builder().userId(1).userName("bob").userAge(23).score(75.3).delFlag(0).createTime(LocalDateTime.now()).build());
users.add(User.builder().userId(2).userName("Allen").userAge(33).score(95D).delFlag(0).createTime(LocalDateTime.now()).build());
users.add(User.builder().userId(3).userName("Mary").userAge(23).score(60D).delFlag(0).createTime(LocalDateTime.now()).build());
users.add(User.builder().userId(4).userName("King").userAge(28).score(56.5).delFlag(0).createTime(LocalDateTime.now()).build());
users.add(User.builder().userId(5).userName("张三").userAge(30).score(85.5).delFlag(0).createTime(LocalDateTime.now()).build());
users.add(User.builder().userId(6).userName("李四").userAge(30).score(85.6).delFlag(1).createTime(LocalDateTime.now()).build());
// 部门数据初始化
depts.add(Dept.builder().deptId(1000).deptName("技术部").deptCode("IT").build());
depts.add(Dept.builder().deptId(1001).deptName("财务部").deptCode("MB").build());
depts.add(Dept.builder().deptId(1002).deptName("商务部").deptCode("MA").build());
depts.add(Dept.builder().deptId(1003).deptName("人事部").deptCode("HR").build());
// 用户部门分配情况初始化
userDepts.add(UserDept.builder().deptId(1000).userId(1).build());
userDepts.add(UserDept.builder().deptId(1000).userId(2).build());
userDepts.add(UserDept.builder().deptId(1000).userId(5).build());
userDepts.add(UserDept.builder().deptId(1002).userId(2).build());
userDepts.add(UserDept.builder().deptId(1002).userId(1).build());
userDepts.add(UserDept.builder().deptId(1003).userId(3).build());
userDepts.add(UserDept.builder().deptId(1003).userId(4).build());
}
public static void main(String[] args) {
System.out.println("=============================== 对象集合处理 =============================");
System.out.println("[排序]按照用户年龄升序:");
Linq.of(users).orderBy(User::getUserAge).toList().forEach(System.out::println);
System.out.println("[排序]按照用户年龄升序、成绩降序:(注意:此写法只能按照最后一个排序逻辑处理)⚠️");
Linq.of(users).orderBy(User::getUserAge).orderByDescending(User::getScore).toList().forEach(System.out::println);
System.out.println("[排序]按照用户年龄降序:");
Linq.of(users).orderByDescending(User::getUserAge).toList().forEach(System.out::println);
System.out.println("[排序]按照用户姓名降序:(支持中英文混合排序-中文转成拼音按照字母先后顺序排序)");
Linq.of(users).orderByDescending(User::getUserName).toList().forEach(System.out::println);
System.out.println("【筛选】年龄在30岁及以上的用户:");// 类似SQL select * from user where user_age >= 30;
Linq.of(users).where(user -> user.getUserAge() >= 30).toList().forEach(System.out::println);
System.out.println("【筛选】年龄在30岁以下并且分数在60以下的用户:");// ≈ select * from user here user_ge < 30 and score < 60;
Linq.of(users).where(user -> user.getUserAge() < 30 && user.getScore() < 60D).toList().forEach(System.out::println);
System.out.println("【筛选】模糊查询 - 根据查找名字中带有‘三’的用户:");// ≈ select * from user where user_name like '%三%';
Linq.of(users).where(user -> user.getUserName().contains("三")).toList().forEach(System.out::println);
System.out.println("【筛选】范围查询 - 查询前三个ID用户:");// ≈ select * from user where user_id in (1, 2, 3, 100);
Linq.of(users).where(user -> Linq.of(1, 2, 3, 100).contains(user.getUserId())).toList().forEach(System.out::println);
System.out.println("[统计] 最大,最小,总和,平均值,用户总数");
// ≈ select max(user_age) from user;
System.out.println("最大年龄:" + Linq.of(users).max(User::getUserAge));
// ≈ select min(user_age) from user;
System.out.println("最小年龄:" + Linq.of(users).min(User::getUserAge));
// ≈ select avg(user_age) from user;
System.out.println("平均年龄:" + Linq.of(users).averageDouble(User::getUserAge));
// ≈ select sum(score) from user;
System.out.println("总成绩:" + Linq.of(users).averageDouble(User::getScore));
// ≈ select count(1) from user;
System.out.println("总用户数:" + Linq.of(users).count());
// ≈ select count(1) from user where score < 90;
System.out.println("分数<70的总用户数:" + Linq.of(users).count(user -> user.getScore() < 90D));
System.out.println("最值 top ");
System.out.println("同类第一个(1):" + Linq.of(users).where(user -> user.getUserAge() == 23).firstOrDefault());
System.out.println("同类第一个(2):" + Linq.of(users).firstOrDefault(user -> user.getUserAge() == 23));
System.out.println("同类最后一个(1):" + Linq.of(users).where(user -> user.getUserAge() == 23).lastOrDefault());
System.out.println("同类最后一个(2):" + Linq.of(users).lastOrDefault(user -> user.getUserAge() == 23));
// ≈ select * from (select ROW_NUMBER() over(order by age desc) as rowNum,*) t wher rowNum > 1
System.out.println("跳过前面多少条数据,取剩下的数据: " + Linq.of(users).orderByDescending(User::getScore).skip(2));
System.out.println("分页查询:");
//跳过第一条,取两条,即取第二条到第四条
// ≈ select * from (select ROW_NUMBER() over(order by age desc) as rowNum,*) t wher rowNum>1 and rowNum<=4
List<User> tmpUsers = Linq.of(users).orderByDescending(User::getUserAge).skip(1).take(3).toList();
tmpUsers.forEach(System.out::println);
System.out.println("分组查询: ");
Linq.of(users).groupBy(User::getUserAge).toList().forEach(item -> {
System.out.println("年龄:" + item.getKey()
+ " 总数:" + item.count(x -> x.getUserId() != null)
+ " userId最大值:" + item.max(User::getUserId)
+ " userId最小值:" + item.min(User::getUserId)
);
});
System.out.println("=============================== 对象集合处理 =============================");
}
}
@Data
@Builder
class User {
private Integer userId;// ID
private String userName;// 姓名
private Integer userAge;// 年龄
private Double score;// 评分
private LocalDateTime createTime;
private Integer delFlag;// 逻辑删除标识(0存在,1删除)
}
@Data
@Builder
class Dept {
private Integer deptId;
private String deptName;
private String deptCode;
}
@Data
@Builder
class UserDept {
private Integer deptId;
private Integer userId;
private Dept deptInfo;
private User userInfo;
}
【2】测试结果
=============================== 对象集合处理 =============================
[排序]按照用户年龄升序:
User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
[排序]按照用户年龄升序、成绩降序:(注意:此写法只能按照最后一个排序逻辑处理)⚠️
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
[排序]按照用户年龄降序:
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
[排序]按照用户姓名降序:(支持中英文混合排序-中文转成拼音按照字母先后顺序排序)
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
【筛选】年龄在30岁及以上的用户:
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
【筛选】年龄在30岁以下并且分数在60以下的用户:
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
【筛选】模糊查询 - 根据查找名字中带有‘三’的用户:
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
【筛选】范围查询 - 查询前三个ID用户:
User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=2, userName=Allen, userAge=33, score=95.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
[统计] 最大,最小,总和,平均值,用户总数
最大年龄:33
最小年龄:23
平均年龄:27.833333333333332
总成绩:76.31666666666666
总用户数:6
分数<70的总用户数:5
最值 top
同类第一个(1):User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
同类第一个(2):User(userId=1, userName=bob, userAge=23, score=75.3, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
同类最后一个(1):User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
同类最后一个(2):User(userId=3, userName=Mary, userAge=23, score=60.0, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
跳过前面多少条数据,取剩下的数据: com.bestvike.linq.enumerable.OrderedPartition@1c53fd30
分页查询:
User(userId=5, userName=张三, userAge=30, score=85.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
User(userId=6, userName=李四, userAge=30, score=85.6, createTime=2024-05-01T13:44:25.886499300, delFlag=1)
User(userId=4, userName=King, userAge=28, score=56.5, createTime=2024-05-01T13:44:25.886499300, delFlag=0)
分组查询:
年龄:23 总数:2 userId最大值:3 userId最小值:1
年龄:33 总数:1 userId最大值:2 userId最小值:2
年龄:28 总数:1 userId最大值:4 userId最小值:4
年龄:30 总数:2 userId最大值:6 userId最小值:5
=============================== 对象集合处理 =============================
三、官方案例
附录
- GitHub 开源地址:GitHub - timandy/linq: LINQ to Objects for Java.
- GitHub 中文文档地址:linq/README_CN.md at master · timandy/linq · GitHub
🙏至此,非常感谢阅读🙏