学习中的问题
学习中发现以下代码中对于最后的apply不是很理解,记录一下
1.MenuController
该控制器中有一个分页查询菜单的方法
//省略注解
public class MenuController extends BaseController{
//省略注解
public R<IPage<Menu>> page(Menu data) {
IPage<Menu> page = getPage();
//后续代码省略
}
}
2.BaseController
跟进处于BaseController中的getPage()方法
public abstract class BaseController {
@Resource
protected HttpServletRequest request;
@Resource
protected HttpServletResponse response;
//当前页
protected static final String CURRENT = "current";
//获取分页对象
protected <T> Page<T> getPage() {
return getPage(false);
}
protected Integer getPageNo() {
return NumberHelper.intValueOf(request.getParameter(CURRENT), 1);
}
protected Integer getPageSize() {
return NumberHelper.intValueOf(request.getParameter(SIZE), DEFAULT_LIMIT);
}
//获取分页对象
protected <T> Page<T> getPage(boolean openSort) {
Integer pageNo = getPageNo();// 页数、
Integer pageSize = getPageSize();// 分页大小
return buildPage(openSort, pageNo, pageSize); // 是否查询分页
}
}
通过request.getParameter(“xxx”)可以获取前端提交来的数据,此处绑定的肯定是前端页面中,用户点击分页工具栏中的第几页,因此约定了常量current,前端分页相关的表单中标签指定的name名字肯定也是name=“current”,通过这样设定,前后端进行了关联,request.getParameter也就拿到了相关页码,如果为空,则默认显示第一页。
同时存在一个问题,getParameter是String类型
public abstract String getParameter(String s)
才需要通过intValueOf()转为int类型
3.NumberHelper
再跟进到NumberHelper中的intValueOf方法
public class NumberHelper {
private static <T, R> R valueOfDef(T t, Function<T, R> function, R def) {
try {
return function.apply(t);
} catch (Exception e) {
return def;
}
}
public static Integer intValueOf(String value, Integer def) {
return valueOfDef(value, (val) -> Integer.valueOf(val), def);
}
开始一直没太看明白此处代码,查找一番后,解释一下
1、Function<T, R> function
Function接口将单个的java对象作为参数,并在方法结束时返回单个java对象
Function是函数式接口
官方文档
java.util.function.Function Java Interface Function<T,R> Parameter Types:
T - the input given to the function
R - the result running the function
Popular Subinterface of Function: UnaryOperator<T>
Function 接口有一个名为apply的非默认方法,接受一个参数,并返回一个参数
apply方法只是简单地对转换过的数据进行传递而已
接受一个T类型的参数,并返回一个R类型的返回值
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
apply使用的测试案例
class FunctionClass implements Function<Ingeger,String>{
public String apply(Integer t){
return Integer.toString(t*t);
}
public static void main(String[] args){
Function<Integer, String> functionClass = new FunctionClass();
//输出4
System.out.println(functionClass.apply(2));
}
}
也可以编写一个内部类来实现apply方法
public class test2{
public staitc void main(String[] args){
Function<Integer,String> innerClass=new Function<Integer,String>(){
public String apply(Integer i){
return Integer.toString(t*t);
}
};
//9
sout(innerClass.apply(3));
}
}
因为Function是函数式接口,可以通过lambda表达式,进行缩写
在这里Function<Integer, String> verboseLambda = (Integer x)-> { return Integer.toString(x*x); };
System.out.println(verboseLambda.apply(5));
同时,使用Java lambda表达式时,左侧不需要对象类型,如果lambda表达式是一行长,则可以省略括号和return关键字,代码则变成了
Function<Integer, String> verboseLambda = (x)-> { Integer.toString(x*x); };
回溯之前不理解的代码,就很好理解了
public class NumberHelper {
//2.调用了apply方法,实际代码就是
//Function<String,Integer> function=(var)->{Integer.valueOf(val);};
//并且,当valueOf方法传null值时,会报NumberFormatException异常
//此处捕捉了异常,当首次登录或者刷新时,没有传递用户点击的页码,则默认显示第一页
private static <T, R> R valueOfDef(T t, Function<T, R> function, R def) {
try {
return function.apply(t);
} catch (Exception e) {
return def;
}
}
//1.通过lambda表达式,将Function对象转为Integer
public static Integer intValueOf(String value, Integer def) {
return valueOfDef(value, (val) -> Integer.valueOf(val), def);
}
参考文章:
https://blog.csdn.net/jlsfa/article/details/105666451