发表于: 2020-08-27 23:27:10
1 1377
今天完成的事情
1. 初探 Lambda 表达式
2.SQL 通配符过滤数据
收获
1. 为什么需要 Lambda 表达式?
在 Java 8 引入的 Lambda 表达式可以允许我们使用更加简洁的代码来创建只有一个抽象方法的接口实例。
在下面这个例子中,三种方式的输出完全一样,我们可以发现 Lambda 表达式的写法更加简洁
/**
* Lambda 表达式与匿名内部类
*
* @author owlwinter
* @date 2020/8/27
*/
public class FunctionalInterfaceTest {
public static void printResult(Add add){
System.out.println("result: " + add.run(2, 3));
}
public static void main(String[] args) {
// Lambda
printResult((a, b) -> a + b);
// 匿名内部类的方式调用
printResult(new Add() {
@Override
public int run(int a, int b) {
return a + b;
}
});
}
}
@FunctionalInterface
interface Add{
/**
* 两数相加
* @param a 参数一
* @param b 参数二
* @return 返回二者之和
*/
int run(int a, int b);
}
2. Lambda 表达式是什么?
Lambda 表达式的类型(目标类型 target type)必须是“函数式接口”。
函数式接口代表只包含一个抽象方法的接口(可以包含多个默认方法、类方法,但是只能够声明一个抽象方法)。
如果是采用匿名内部类的语法来创建函数式接口的实例,那么只需要实现一个抽象方法就好。这个时候我们还可以使用 Lambda 表达式的方式来创建该对象,Lambda 表达式创建出来的对象的目标类型就是这个函数式接口。
因此 Lambda 表达式的结果就是一个对象,程序中也完全可以使用 Lambda 表达式进行赋值。
Lambda 的实质是去实现匿名方法,因此它只能够实现特定的函数式接口中的唯一方法。这意味着 Lambda 表达式有如下的限制:
- 1. Lambda 表达式的目标类型必须明确是一个函数式接口
- 2. Lambda 表达式只能为函数式接口创建对象。Lambda 表达式只能实现一个方法,因此它只能为只有一个抽象方法的接口(函数是接口)创建对象。
3. @FunctionalInterface 注解有什么用?
在 Java 8 中专门给函数式接口提供了一个注解 @FunctionalInterface,这个注解的有无对程序的运行没有任何影响,只不过是在编译的时候编译器会严格检查该接口必须是一个函数式接口,否则就报错。
4. 如何确定表达式的类型?
使用以下语句创建 Lambda 表达式会报错,因为 Lambda 表达式的类型错误。
Object obj = () -> a + b;
为了保证 Lambda 表达式是一个明确的函数式接口,可以有如下的三种常见方式:
- 1. 将 Lambda 表达式赋值给函数时接口类型的变量
Add add = () -> a + b;
- 2. 将 Lambda 表达式作为函数式接口类型的参数传递给某个方法
public static void printResult(Add add){
System.out.println( add.run(2, 3) );
}
public static void main(String[] args){
printResult( (a, b) -> a + b);
}
- 3. 使用函数式接口对 Lambda 表达式进行强制转型
Object obj = (Add) (a, b) -> a + b;
5. 方法引用与构造器引用
我们可以在 Lambda 表达式中使用方法引用与构造器引用,使用引用的时候 Lambda 表达式中只能有一行代码。
- 引用类的方式
public class FunctionalReferenceTest {
public static void main(String[] args) {
/**
* 使用引用类的方式
* */
// Converter converter = from -> Integer.valueOf(from);
// System.out.println(converter.convert("00786"));
Converter converter1 = Integer::valueOf;
System.out.println(converter1.convert("00786"));
}
}
@FunctionalInterface
interface Converter{
Integer convert(String from);
}
上面那也就是调用 Integer 类的 valueOf() 方法来实现 Converter 函数式接口中唯一的抽象方法。
- 引用特定对象的实例方法
public class FunctionalReferenceTest {
public static void main(String[] args) {
/**
* 引用特定对象的实例方法
* */
// Converter converter2 = from -> "jnshu.com".indexOf(from);
// System.out.println(converter2.convert("."));
Converter converter3 = "jnshu.com"::indexOf;
System.out.println(converter3.convert("."));
}
}
@FunctionalInterface
interface Converter{
Integer convert(String from);
}
- 引用某类对象的实例方法
public class FunctionalReferenceTest {
public static void main(String[] args) {
/**
* 引用某类对象的实例方法
* */
// StrTest strTest = (string, start, end) -> string.substring(start, end);
// System.out.println(strTest.sub("jnshu.com", 0, 5));
StrTest strTest1 = String::substring;
System.out.println(strTest1.sub("jnshu.com", 0, 5));
}
}
@FunctionalInterface
interface StrTest{
String sub(String string, int start, int end);
}
- 引用构造器
public static void main(String[] args) {
/**
* 引用构造器
* */
// StrConstruction strConstruction = str -> new String(str);
// System.out.println(strConstruction.string("abc"));
StrConstruction strConstruction1 = String::new;
System.out.println(strConstruction1.string("abc"));
}
}
@FunctionalInterface
interface StrConstruction{
String string(String str);
}
Lambda 表达式的加入确实可以起到简洁代码的作用,但是需要设计者把接口定义的足够清晰,不要产生歧义。
6. SQL 通配符过滤数据
LIKE 操作符
如果我们想要在数据库中搜索特定模式的文本,那么之前那些操作符都不起作用了,这个时候就需要使用通配符了。
通配符的本身其实是 SQL 的 WHERE 子句中有特殊含义的字符。
为了在搜索子句中使用通配符,必须是hi用 LIKE 操作符。后面利用通配符进行匹配
- 百分号通配符(%)
最常使用的是百分号通配符。在搜索中 % 表示任意字符出现任意次数。
例如,匹配 Fish 开头的任意文本:
SELECT name, price
FROM goods
WHERE name LIKE 'Fish%';
当然 % 也可以放在文本的前后或者中间。
需要注意的一些事情:
- 是会不会匹配大小写取决于数据库的配置。
- 有一些数据库使用空格来填补字段的内容,此时匹配形如 F%Y 的内容的话就会和我们的预期不符,很多 'Y' 结尾的文本后面都被空格填充,匹配不到。(试了一下 MySQL 的 cahr varchar 都没有这个问题)
- '%' 不会匹配 NULL 行
- 下划线通配符(_)
一个下划线只会匹配一个任意字符,不能多也不能少
SELECT name, price
FROM goods
WHERE name LIKE 'app_e';
- 方括号匹配([])(实测 MySQL 不支持)
方括号用来匹配一个指定的字符集,它必须匹配指定位置的一个字符。
SELECT name, price
FROM goods
WHERE name LIKE '[abc]%';
以上一句匹配以 a, b, c 中任意一个字符开头的所有文本。
这个排版我已经放弃了,修真院不考虑支持一下 MakrDown 吗?
评论