JavaFX Tutorials

Thursday, September 8, 2016

Rewriting Nested Loops as Java Streams

This post rewrites a nested loop as a pair of Java Streams.  While there isn't much savings in comparing each statement in isolation, there will be more value if the first Stream's output is retained for other logic.  For example, if there are several blocks of code that need "activeRolesIds", then it's worthwhile to factor out that code in a Stream.

This statement sets one or more ToggleButton to selected if that ToggleButton's userData is found in the activeRoles list which is returned from the JavaFX ListProperty roles.getValue().

       
for( RoleDTO activeRole : roles.getValue() ) {
    for( Node availableRoleNode : hboxRoles.getChildren() ) {
        if( availableRoleNode.getUserData().equals( activeRole.getRoleId() ) ) {
            ( (ToggleButton) availableRoleNode ).setSelected( true );
            break;
            }
        }
}

This can be replaced with two Streams.  The first Stream maps a List of Integer values that is used in the second Stream's filter predicate.

List<Integer> activeRoleIds = roles.getValue()
    .stream()
    .map( (r) -> r.getRoleId() )
    .collect(Collectors.toList());

hboxRoles.getChildren()
    .stream()
    .filter( (n) -> activeRoleIds.contains(n.getUserData()) )
    .forEach( (n) -> ((ToggleButton)n).setSelected(true) );

Both the nested loops and the pair of Streams will set the appropriate ToggleButton state.  The Streams versions will offer a savings if later blocks of code also can use the activeRoleIds List.

Update

Here's another example of a loop (not a nested loop) rewritten as a Lambda.

hboxRoles.getChildren().clear();
for( RoleDTO role : availableRoles ) {
    ToggleButton tb = new ToggleButton( role.getRoleName() );
    tb.setUserData( role.getRoleId() );
    hboxRoles.getChildren().add( tb );
}

The Lambda uses the map() method to convert transfer objects (RoleDTO) into JavaFX controls (ToggleButton).

hboxRoles.getChildren().setAll(

    availableRoles
        .stream()
        .map( (r) ->l; {
            ToggleButton tb = new ToggleButton(r.getRoleName());
            tb.setUserData( r.getRoleId() );
            return tb;
        })
        .collect(Collectors.toList())

);

No comments:

Post a Comment