繁体   English   中英

Java 8:如何在JoinRowSets上使用lambda表达式?

[英]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));
    }

请注意, currentJcurrentColValue 实际上是final的 ,这意味着您可以在不更改程序的情况下向它们添加final修饰符。 在lambda表达式中使用的局部变量必须是final有效的final


顺便说一句,不要考虑“在迭代之间重用lambda”。 在大多数情况下,JRE将尽可能重用为lambda表达式创建的实例。 无论如何,JDBC操作都超过了为lambda表达式创建的临时对象所施加的所有开销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM