目前我有一个元组的ArrayDeque,如下所示(我认为这里有一个类可能有帮助),目前已经过序列化并通过网络发送:
private ArrayDeque<Triple<Integer, Object, Class>> paramList = new ArrayDeque<>();
元组中的对象类型可以是原始的,例如int,bool或真实类,例如Date,time(没有一个是我的实现)。
现在我正在遍历列表并根据它的类类型调用方法,显然这会变得繁琐的修改和更新。 例如(st是PreparedStatement):
for (Triple<Integer, Object, Class> param : paramList) {
if(param.getMiddle() instanceof String){
st.setString(parm.getLeft(),param.getMiddle());
}else if(param.getMiddle() instanceof Integer){
st.setInt(parm.getLeft(),param.getMiddle());
} //... more class type checks doing the same thing
}
我遇到了这篇https://stackoverflow.com/a/5579385/5858208帖子,但由于这不是我实施的课程,所以我做不了多少。
所以我的问题是,是否有一种更有效和可维护的方式来实现这个想法,因为我在元组对象中确切地说它是什么类?
答案 0 :(得分:0)
您可以创建一个Map
,其中包含代码支持的所有类的键,以及作为调用正确setter的lambda表达式的值。
这些方面的东西:
@FunctionalInterface
interface PSConsumer<T,U> {
void accept(T t, U u) throws SQLException;
}
private Map<Class<?>, PSConsumer<PreparedStatement, Triple<Integer, Object, Class<?>>>> setters = new HashMap<>();
{
setters.put(String.class, (st, param) -> st.setString(param.getLeft(), (String) param.getMiddle()));
setters.put(Integer.class, (st, param) -> st.setInt(param.getLeft(), (Integer) param.getMiddle()));
// add here code for all the classes that you support
}
for (Triple<Integer, Object, Class<?>> param : paramList) {
// this will throw an NPE if param.getMiddle() returns null or it's class is not in the map:
setters.get(param.getMiddle().getClass()).accept(st, param);
}
要以类似的方式提取值,您可以使用以下定义:
@FunctionalInterface
interface RSExtractor<T,U,R> {
R apply(T t, U u) throws SQLException;
}
private Map<Class<?>, RSExtractor<ResultSet, Triple<Integer, Object, Class<?>>, Object>> getters = new HashMap<>();
{
getters.put(String.class, (rs, param) -> rs.getString(param.getLeft()));
getters.put(Integer.class, (rs, param) -> rs.getInt(param.getLeft()));
}
public List<Object> get(ResultSet rs) throws SQLException {
List<Object> results = new ArrayList<>();
for (Triple<Integer, Object, Class<?>> param : paramList) {
results.add(getters.get(param.getRight()).apply(rs, param));
}
return results;
}
请注意,接口RSExtractor
看起来很像接口java.util.function.BiFunction
,但此接口允许实现方法抛出SQLException