How to get a value from lambda in Java?

If you reached this article, you most likely face one of these errors, and trying to get rid of one, get another: "variable used in lambda expression should be final or effectively final", "variable may be not initialized", "cannot assign a value to final variable". For my explanation I will use vaadin's Window.
public class SelectionWindow extends Window {
	private Button okButton = null;
	private BeanItemContainer container;
	private LegalEntity selected;
 
	public SelectionWindow(List items){
	...
		setClosable(false);
		container = new BeanItemContainer<>(Entity.class, items);
		grid = new Grid(container);
		grid.addSelectionListener(event -> {
			Object selectedObj = grid.getSelectedRow();
			selected = (LegalEntity) selectedObj;
			if (okButton != null) {
				okButton.setEnabled(selected != null);
			}
 		});
	}
 
	// the only way to close the window
	public void setOkButtonListener(Button.ClickListener listener) {
        okButton.addClickListener(listener);
    }
 
	// this way we get selected item
	public Entity getSelected() {
        return selected;
    }
 
}
So, to pass params into the Window you just add arguments to the constructor. In my case I don't need a private field List items. If I did, I would add:
private List items;
and a line to constructor:
this.items = items;
You can use setters as well. Case 1. You just need to read selected value and to use right in the code of the listener.
SelectionWindow selectionWindow = new SelectionWindow(items);
selectionWindow.setOkButtonListener(clickEvent -> {
    Entity selected = selectionWindow.getSelected();
    populateFromSelection(selected);
    selectionWindow.close();
});
 
private void populateFromSingleSuggestion(LegalEntity legalEntity) {
	// react upon the new value
}
The point is that you know in the code when your Window gets closed. On this event you can read any field/state from it (you can add getters) and update your UI. Case 2. You want to read a value and assign to a variable with a wider scope. Use atomic reference.
final AtomicReference reference = new AtomicReference<>();
 
selectionWindow.setOkButtonListener(clickEvent -> {
                reference.set(selectionWindow.getSelected());
                selectionWindow.close();
            });
Then get your item with reference.get().
You can leave a response, or trackback from your own site.

Leave a Reply