Lambda using outer connection variable inside forEach

user1578872 :

I have a connection object which is created once and used inside forEach. Unable to use the connection object in finally as it is final without the initial value to be used inside 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();
            }
        }

Is there any other better way?

Holger :

You should use the try-with-resources Statement which exists since Java 7:

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
 }

Since this eliminates the need to call close manually, you don’t have to preinitialize the variable with null. As a bonus, it can handle exceptions thrown in the close method correctly.

Even if your close operation is not an AutoClosable.close(), it can easily get adapted:

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
}

and if you insist on your original finally logic:

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
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=308341&siteId=1