The problem I was trying to solve was one where I had two identical code paths. The only difference between the two was the data type of one of the parameters. Basically, I had
private List<StylesheetContainer> gatherParentStylesheets(Parent parent)and
private List<StylesheetContainer> gatherSceneStylesheets(Scene parent)
The main difference between these two methods was a call to add the Parent to one list, and a call to add the Scene to a different list (the idea is that there is one list of Parents that refer to the stylesheet and another list of Scenes that refer to the stylesheet). I tried different ways of refactoring these methods into one and kept coming back to the same thought; that if I could pass both the parent or scene and the list as parameters, I'd be set.
I started to think about whether or not lambdas could help me. What if I passed a function that did that for me? What I really wanted to do was say that this Scene or Parent refers to the StylesheetContainer and I came up with this interface.
@FunctionalInterface
static interface Referent {void addReferenceTo(StylesheetContainer c) }
Now I could pass the "addReferenceTo" function to a method and could refactor the code into a single method.
private List<StylesheetContainer> processStylesheets(List<String> stylesheets, StylesheetContainer.Referent referent)
In this method, I just do:
referent.addReferenceTo(container);
And call it like so:
final List<StylesheetContainer> list = processStylesheets(sceneStylesheets, (c) -> c.sceneUsers.add(scene));or
final List<StylesheetContainer> list = processStylesheets(parentStylesheets, (c) -> c.parentUsers.add(parent));
In retrospect, I could have done the same thing with an Interface and an anonymous inner class. Or I could have just used 'instance of'. But I think the lambda solution is rather elegant.
You can see the change here, in the diffs to StyleManager.