Lambda在forEach中使用外部连接变量

use*_*872 1 java lambda java-8

我有一个创建一次的连接对象,并在forEach中使用。如果没有在forEach内部使用初始值,则无法最终使用连接对象,因为它是最终的。

final Connection connection;
        try {
            connection = db.createConnection();

            final Map<String, String> dataMap = adminClient.list().values();

            dataMap.entrySet().forEach(entry -> {

                // Need to use connection object here ...
                // Unable to use the connection if it is not final and to make it final, not initializing it to null  ...
            });

        }
        catch (final Exception e) {
            e.printStackTrace();
        }
        finally {
            // Unable to use the connection here if it is not initialized to null ...
            if (connection != null) {
                connection.close();
            }
        }
Run Code Online (Sandbox Code Playgroud)

还有其他更好的方法吗?

Hol*_*ger 5

您应该使用Java 7以来存在的try-with-resources语句

try(Connection connection = db.createConnection()) {
    final Map<String, String> dataMap = adminClient.list().values();
    dataMap.entrySet().forEach(entry -> {
        // use connection object here ...
    });
 }
 catch (final Exception e) {
    e.printStackTrace(); // replace with real handling later
 }
Run Code Online (Sandbox Code Playgroud)

由于这消除了close手动调用的需要,因此您不必使用来预先初始化变量null。另外,它可以close正确处理方法中引发的异常。

即使您的close操作不是AutoClosable.close(),也可以轻松进行调整:

try {
    Connection connection = db.createConnection();
    try(AutoCloseable c = () -> connection.close(timeout)) {
        final Map<String, String> dataMap = adminClient.list().values();
        dataMap.entrySet().forEach(entry -> {
            // use connection object here ...
        });
    }
}
catch (final Exception e) {
    e.printStackTrace(); // replace with real handling later
}
Run Code Online (Sandbox Code Playgroud)

如果您坚持原来的finally逻辑:

try {
    Connection connection = db.createConnection();
    try {
        final Map<String, String> dataMap = adminClient.list().values();
        dataMap.entrySet().forEach(entry -> {
            // use connection object here ...
        });
    }
    finally {
        if(connection != null) connection.close(timeout);
    }
}
catch (final Exception e) {
    e.printStackTrace(); // replace with real handling later
}
Run Code Online (Sandbox Code Playgroud)