使用java8的lambdas作为方法参数以避免冗余
我有一个类,有很多这样的方法(非常简化):使用java8的lambdas作为方法参数以避免冗余,java,lambda,java-8,Java,Lambda,Java 8,我有一个类,有很多这样的方法(非常简化): public Record[] getRecordForXXX(String username, String param1) throws MyException { User user = getUser(String username); // Always the same MyObject myObj = getMyObject(param1); // Always the same // Here is the o
public Record[] getRecordForXXX(String username, String param1) throws MyException {
User user = getUser(String username); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
// Here is the only line of code, this is different in any of thoose methods
Record[] recs = getRecords1(user, myObject); // or getRecords2(user, myObject) ...
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}
是否有任何方法可以使用lambdas来避免冗余,如:
public Record[] getRecord(String userName, String param1, XXX method) throws MyException {
User user = getUser(String username); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
// => Call the given 'method' using the parameters user and myObj and returning records
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}
我知道,我可以使用某种接口(命令模式)来实现这一点,但我喜欢使用更具功能性的方法。。。蒂亚 public Record[]getRecordForXXX(字符串用户名、字符串参数1、双函数加载器)抛出MyException{
public Record[] getRecordForXXX(String username, String param1, BiFunction<User, MyObject, Record[]> loader) throws MyException {
User user = getUser(String username); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
Record[] recs = loader.apply(user, myObject);
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}
getRecordForXXX("user", "param1", ClassName::getRecords1);
getRecordForXXX("user", "param1", ClassName::getRecords2);
User User=getUser(字符串用户名);//始终相同
MyObject myObj=getMyObject(参数1);//始终相同
记录[]recs=loader.apply(用户,myObject);
//处理那些记录总是一样的。。。
HandlerRecords(recs);//始终不变
return recs;//始终相同
}
getRecordForXXX(“用户”,“参数1”,类名::getRecords1);
getRecordForXXX(“用户”,“参数1”,类名::getRecords2);
试试这个
public Record[] getRecord(String userName, String param1, BiFunction<User, MyObject, Record[]> method) throws MyException {
User user = getUser(String username); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
Record[] recs = method.apply(user, myObj);
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}
尽管lambdas在这里可能很有效,但您不会将其用于真正的用途。您正在寻找和枚举可以很好地实现策略模式
enum Type {
XXX {
@Override
Record[] forType(User user, MyObject obj) {
// Something here.
return null;
}
},
YYY {
@Override
Record[] forType(User user, MyObject obj) {
// Something here.
return null;
}
};
abstract Record[] forType(User user, MyObject obj);
}
public Record[] getRecord(String userName, String param1, Type type) throws MyException {
User user = getUser(userName); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
// Use the Type to choose the strategy to grow the records.
Recs recs = type.forType(user, myObj);
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}
调查方法参数将是
BiFunction
。这足够了吗?@ajb不幸的是,这还不够:我需要QuadFunction)
。但是实现类似于BiFunction
的接口应该不那么困难它们必须是静态的吗?@t777:对于非静态方法,您也可以使用this::getRecords1
和this::getRecords2
。@t777如果您有User
的getRecords1
方法,它接受一个MyObject
参数并返回Records[]
,您可以使用User::getRecords1
。此外,您不必使用方法引用(语法:
);您可以使用lambda作为第三个参数来getRecordForXXX
。事实上,我有两个以上的参数。因此,我需要实现自己的功能接口吗?最好编写自己的功能接口。假设参数的数量和类型是恒定的,这应该很简单。这是一个非常好的主意!如果这在(spring)事务上下文中有效,我必须进行评估。为什么您认为:“您不会使用它们[lambdas]来实现它们的真正用途”?@t777-为什么您认为…-因为lambda是简单策略之外的几个步骤——它们不仅提供了功能接口,还提供了类型安全性和本地参数封装以及各种其他好处。在这种情况下,他们是敲开螺母的大锤。当你遇到战略问题时,你应该使用战略解决方案。战略是行之有效的模式,不需要新的闪亮事物。当然,您可以在lambdas上以相同的方式实现,因为您需要指定一些通用接口,但不需要+1.这是我的解决方案
enum Type {
XXX {
@Override
Record[] forType(User user, MyObject obj) {
// Something here.
return null;
}
},
YYY {
@Override
Record[] forType(User user, MyObject obj) {
// Something here.
return null;
}
};
abstract Record[] forType(User user, MyObject obj);
}
public Record[] getRecord(String userName, String param1, Type type) throws MyException {
User user = getUser(userName); // Always the same
MyObject myObj = getMyObject(param1); // Always the same
// Use the Type to choose the strategy to grow the records.
Recs recs = type.forType(user, myObj);
// Handle those records always the same ...
handleRecords(recs); // Always the same
return recs; // Always the same
}