This popular answer on Stack Overflow has this to say about the difference between functional programming and object-oriented programming:
Object-oriented
Lambda expressions can make it easier to set up (very) poor man's pattern matching. Same technique can be used to make a Visitor easier to build.
static interface Animal {
// can also make it a default method
// to avoid having to pass animal as an explicit parameter
static void match(
Animal animal,
Consumer dogAction,
Consumer catAction,
Consumer fishAction,
Consumer birdAction
) {
if (animal instanceof Cat) {
catAction.accept((Cat) animal);
} else if (animal instanceof Dog) {
dogAction.accept((Dog) animal);
} else if (animal instanceof Fish) {
fishAction.accept((Fish) animal);
} else if (animal instanceof Bird) {
birdAction.accept((Bird) animal);
} else {
throw new AssertionError(animal.getClass());
}
}
}
static void jump(Animal animal) {
Animal.match(animal,
Dog::hop,
Cat::leap,
fish -> {
if (fish.canJump()) {
fish.jump();
} else {
fish.swim();
}
},
Bird::soar
);
}