[英]Java 8: how to use lambda expressions on JoinRowSets?
我正在开发一项功能,该功能将在我公司的某些产品中使用,因此我没有特定于产品的代码。
我将2个查询的结果存储在2个JoinRowSet
对象上(我必须使用JoinRowSet
因为稍后我必须将其他查询的结果与这些查询结合在一起)。 然后,我需要与这2个JoinRowSet
相交,但是我不知道它们“属于”哪个类(我不知道查询是否将返回人员,联系人,部门或任何其他东西)。 有人告诉我应该使用lambda表达式来执行此操作,但是发现一些问题。
我已经将其中一个JoinRowSet
转换为Collection(我不知道如何直接在JoinRowSet
上使用lambda表达式),然后我遍历其中一个JoinRowSet
,对于此JoinRowSet
每一列,我想获取初始Collection上与该列具有相同值的记录。 但是,由于我不知道数据的类,所以我无法执行u.getAge()
因为我没有属性名。
这是我的方法:
public static void testLambdas() throws SQLException {
... //set the needed stuff to connect to database and query data
JoinRowSet jrs1 = ... //result from query 1
JoinRowSet jrs2 = ... //result from query 2
Collection<Row> jrs2Collection = (Collection<Row>) jrs2.getRowSets();//collection to use on lambda expression
while (jrs1.next()) {
ResultSetMetaData metadata = jrs1.getMetaData();
for (int j = 1; j <= metadata.getColumnCount(); j++) {
String dataType = metadata.getColumnTypeName(j);
Object colValue = null;
if (dataType.equals("NUMBER")) {
colValue = jrs1.getBigDecimal(j);
} else if (dataType.equals("VARCHAR2")) {
colValue = jrs1.getString(j);
} else if (dataType.equals("DATE")) {
colValue = jrs1.getTimestamp(j);
}
System.out.println(metadata.getColumnName(j)+ " (" + dataType +"): "+ colValue);
Object o = jrs2Collection.stream()
.filter(u -> {
try {
return (u.getColumnObject(j).equals(colValue));
} catch (Exception e) {
e.printStackTrace();
return false;
}
})
.collect(Collectors.toCollection(TreeSet::new));
}
}
}
请忽略以下事实:这种lambda表达式的使用是在一段时间内,并且不会在每次迭代中重复使用。 如果可以解决我现在遇到的问题,我会解决的。
我必须将try-catch添加到过滤器中,因为它返回了Unhandled异常类型SQLException
。 添加此try-catch之后,我得到了在封闭范围内定义的Local变量j
必须在u.getColumnObject(j)
上为final或有效地为final 。
我不知道我在做什么是执行此操作的最佳方法,或者我做错了什么(我的两个同事都在查看我的代码,也不知道如何解决此问题)。
对此,我将不胜感激。
不清楚在循环中创建集合而不使用它们时要尝试做什么。 因此,我无法告诉您是否有更好的解决方案。
关于错误,错误消息非常清楚。 您不能在lambda中使用可变的局部变量。 但是,解决方案非常简单:您可以将可变变量的内容分配给不可变变量:
for (int j = 1; j <= metadata.getColumnCount(); j++) {
// …
int currentJ = j;
Object currentColValue = colValue;
Object o = jrs2Collection.stream()
.filter(u -> {
try {
return (u.getColumnObject(currentJ).equals(currentColValue));
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
)
.collect(Collectors.toCollection(TreeSet::new));
}
请注意, currentJ
和currentColValue
实际上是final的 ,这意味着您可以在不更改程序的情况下向它们添加final
修饰符。 在lambda表达式中使用的局部变量必须是final
或有效的final 。
顺便说一句,不要考虑“在迭代之间重用lambda”。 在大多数情况下,JRE将尽可能重用为lambda表达式创建的实例。 无论如何,JDBC操作都超过了为lambda表达式创建的临时对象所施加的所有开销。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.