🙏废话不多说系列,直接开整🙏
一、LinQ 简介
LINQ(Language Integrated Query)是C#等编程语言中用于查询和操作数据的一种技术。在LINQ中,有许多操作符用于构建查询和转换数据。以下是一些常用的LINQ操作符:
- Where:用于根据指定的条件筛选序列的元素。
- Select:用于根据输入序列中的元素创建相应的输出序列中的元素。输出序列中的元素类型可以与输入序列中的元素类型相同,也可以不同。
- SelectMany:用于根据输入序列中的每一个元素,在输出序列中创建相应的零个或者多个元素。与Select操作符不同,SelectMany操作符可以创建多个输出元素。
- OrderBy:按升序对序列的元素进行排序。
- OrderByDescending:按降序对序列的元素进行排序。
- ThenBy:对已排序的序列按升序进行进一步排序。
- ThenByDescending:对已排序的序列按降序进行进一步排序。
- GroupBy:根据指定的键对序列的元素进行分组。
- Join:将两个序列的元素进行关联。
- Union:返回两个序列的并集。
- Distinct:返回序列的不重复元素。
- Count:返回集合项数。
- Sum:计算序列中的所有数字的和。
- Min:返回集合中的最小值。
- Max:返回集合中的最大值。
- Average:返回集合中的平均值。
- Aggregate:传递一个lambda表达式,该表达式对所有的值进行聚合。
- Any:确定序列是否包含任何元素。
- First:返回序列的第一个元素。
- FirstOrDefault:返回序列的第一个元素,如果序列为空则返回默认值。
- Last:返回序列的最后一个元素。
此外,还有如Take、TakeWhile、Skip、SkipWhile等操作符,用于从序列中返回或跳过指定数量的元素。
以上只是LINQ中的一部分操作符,但涵盖了最常用的部分。不同的编程语言可能还提供了额外的LINQ操作符,具体取决于该语言的实现和版本。
二、自定义 LinQ
package com.example.mybatisflexdemo;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class LinqUtils {
// 类似于LINQ的Where方法
public static <T> List<T> where(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).collect(Collectors.toList());
}
// 类似于LINQ的Select方法
public static <T, R> List<R> select(List<T> list, Function<T, R> mapper) {
return list.stream().map(mapper).collect(Collectors.toList());
}
// 类似于LINQ的FirstOrDefault方法
public static <T> Optional<T> firstOrDefault(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).findFirst();
}
// 类似于LINQ的Any方法
public static <T> boolean any(List<T> list, Predicate<T> predicate) {
return list.stream().anyMatch(predicate);
}
// 类似于LINQ的All方法
public static <T> boolean all(List<T> list, Predicate<T> predicate) {
return list.stream().allMatch(predicate);
}
// 示例方法,可以添加更多自定义方法...
// 统计
public static <T> Long count(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).count();
}
// 模拟LINQ的None
public static <T> boolean none(List<T> list, Predicate<T> predicate) {
return list.stream().noneMatch(predicate);
}
// 模拟LINQ的First
public static <T> Optional<T> first(List<T> list) {
return list.stream().findFirst();
}
// 模拟LINQ的FirstOrDefault(需要默认值)
public static <T> T firstOrDefaultValue(List<T> list, T defaultValue) {
return list.stream().findFirst().orElse(defaultValue);
}
// 模拟LINQ的Last
public static <T> Optional<T> last(List<T> list, Predicate<T> predicate) {
return list.stream().filter(predicate).reduce((first, second) -> second);
}
public static <T> Optional<T> last(List<T> list) {
return list.stream().reduce((first, second) -> second);
}
// 模拟LINQ的LastOrDefault(需要默认值)
public static <T> T lastOrDefault(List<T> list, T defaultValue) {
return list.stream().reduce(defaultValue, (a, b) -> b);
}
// 模拟LINQ的Take(获取前n个元素)
public static <T> List<T> take(List<T> list, int n) {
return list.stream().limit(n).collect(Collectors.toList());
}
// 模拟LINQ的Skip(跳过前n个元素)
public static <T> List<T> skip(List<T> list, int n) {
return list.stream().skip(n).collect(Collectors.toList());
}
// 模拟LINQ的OrderBy(需要额外的比较器)
public static <T> List<T> orderBy(List<T> list, Comparator<T> comparator) {
return list.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
// 模拟LINQ的GroupBy(返回Map)
public static <T, K> Map<K, List<T>> groupBy(List<T> list, Function<T, K> classifier) {
return list.stream()
.collect(Collectors.groupingBy(classifier));
}
// 模拟LINQ的Count
public static long count(List<?> list) {
return list.stream().count();
}
// 模拟LINQ的Sum(假设列表包含数字)
public static int sum(List<Integer> list) {
return list.stream()
.mapToInt(Integer::intValue)
.sum();
}
// 模拟LINQ的Average(假设列表包含数字)
public static OptionalDouble average(List<Integer> list) {
return list.stream()
.mapToDouble(Integer::doubleValue)
.average();
}
// 模拟LINQ的Min(假设列表包含可比较对象)
public static Optional<Integer> min(List<Integer> list) {
return list.stream()
.min(Integer::compareTo);
}
// 模拟LINQ的Max(假设列表包含可比较对象)
public static Optional<Integer> max(List<Integer> list) {
return list.stream()
.max(Integer::compareTo);
}
}
三、测试自定义 LinQ 工具
针对 LINQ 的特点测试了一些常用的接口函数,是的程序写法更加接近 SQL 语法规则。
// 使用示例
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
System.out.println("测试初始数据:" + String.join(",", numbers.stream().map(String::valueOf).toList()));
System.out.println("JDK8统计:" + numbers.stream().filter(i -> i <= 3).count());
System.out.println("自定义LINQ统计:" + LinqUtils.count(numbers, i -> i <= 3));
// 使用where方法过滤偶数
List<Integer> evenNumbers = LinqUtils.where(numbers, n -> n % 2 == 0);
System.out.println("使用where方法过滤偶数: " + evenNumbers); // 输出: [2, 4]
// 使用select方法将整数列表转换为字符串列表
List<String> stringNumbers = LinqUtils.select(numbers, String::valueOf);
System.out.println("使用select方法将整数列表转换为字符串列表: " + stringNumbers); // 输出: [1, 2, 3, 4, 5]
// 使用firstOrDefault方法获取第一个偶数,或者为空
Optional<Integer> firstEven = LinqUtils.firstOrDefault(numbers, n -> n % 2 == 0);
firstEven.ifPresent(i -> System.out.println("使用firstOrDefault方法获取第一个偶数,或者为空: " + i)); // 输出: 2
// 使用any方法检查是否有任何偶数大于3
boolean hasEvenGreaterThan3 = LinqUtils.any(numbers, n -> n > 3 && n % 2 == 0);
System.out.println("使用any方法检查是否有任何偶数大于3:" + hasEvenGreaterThan3); // 输出: true
// 使用all方法检查所有数字是否都小于6
boolean allLessThan6 = LinqUtils.all(numbers, n -> n < 6);
System.out.println("使用all方法检查所有数字是否都小于6: " + allLessThan6); // 输出: true
List<Integer> sortedNumbers = orderBy(numbers, Integer::compareTo);
System.out.println("Sorted numbers: " + sortedNumbers);
Map<Boolean, List<Integer>> groupedByOddEven = groupBy(numbers, n -> n % 2 == 0);
System.out.println("Grouped by odd/even: " + groupedByOddEven);
// 统计元素数量
long count = count(numbers);
System.out.println("Count: " + count);
// 统计 最大值
int sum = sum(numbers);
System.out.println("Sum: " + sum);
// 统计平均值
OptionalDouble average = average(numbers);
average.ifPresent(avg -> System.out.println("Average: " + avg));
// 统计 最小值
Optional<Integer> min = min(numbers);
min.ifPresent(m -> System.out.println("Min: " + m));
// 统计 最大值
Optional<Integer> max = max(numbers);
max.ifPresent(m -> System.out.println("Max: " + m));
// 判断是否: 没有负数吗?
boolean noneNegative = none(numbers, n -> n < 0);
System.out.println("Are there no negative numbers? " + noneNegative);
// 第一个值:
Optional<Integer> firstNumber = first(numbers);
firstNumber.ifPresent(n -> System.out.println("First number: " + n));
// 第一个值or默认值:
int firstOrDefault = firstOrDefaultValue(numbers, -1);
System.out.println("FirstOrDefault: " + firstOrDefault);
// 最后一个值
Optional<Integer> lastNumber = last(numbers);
lastNumber.ifPresent(n -> System.out.println("Last number: " + n));
int lastOrDefault = lastOrDefault(numbers, -1);
System.out.println("LastOrDefault: " + lastOrDefault);
List<Integer> firstThree = take(numbers, 3);
System.out.println("First three numbers: " + firstThree);
List<Integer> skipFirstThree = skip(numbers, 3);
System.out.println("Skip first three numbers: " + skipFirstThree);
}
测试结果:
测试初始数据:1,2,3,4,5
JDK8统计:3
自定义LINQ统计:3
使用where方法过滤偶数: [2, 4]
使用select方法将整数列表转换为字符串列表: [1, 2, 3, 4, 5]
使用firstOrDefault方法获取第一个偶数,或者为空: 2
使用any方法检查是否有任何偶数大于3:true
使用all方法检查所有数字是否都小于6: true
Sorted numbers: [1, 2, 3, 4, 5]
Grouped by odd/even: {false=[1, 3, 5], true=[2, 4]}
Count: 5
Sum: 15
Average: 3.0
Min: 1
Max: 5
Are there no negative numbers? true
First number: 1
FirstOrDefault: 1
Last number: 5
LastOrDefault: 5
First three numbers: [1, 2, 3]
Skip first three numbers: [4, 5]
🙏至此,非常感谢阅读🙏