Clean Code and Java 8

I write more and more Java 8 code. But within the last week I wondered if streams and lambdas may lead to code that nobody understands (like generics back in the days). But I’ll give you a few examples and my opinion about it.

Messy Code because of Streams and Lambdas?

I wrote some code like this:

    .filter(item -> mapper.hasMappingFor(item))
    .map(item -> mapper.map(item))

Wouldn’t it be more readable for other developers seeing the code for the first time, if I write it like that?

for(Item item : items) {
    if (mapper.hasMappingFor(item)) return mapper.map(item);

Or does it just feel that way because I see these for-loops every day? In general, I really like fluent APIs and for me the stream-solution seems to be very elegant. Are developers complaining about Java 8 code because they are just old-fashioned? Or is it really harder to understand and maybe also harder to maintain?

Elegance of Streams and Lambdas

Last week I attend at one of our internal coding events and we worked on the yahtzee kata. I had to leave early but because I had a lot of ideas, I worked on that kata on the train, focusing on Java 8 features and check if the code feels clean. The problem I was solving: get all possible yahtzee categories for a given roll. I solved that with an enumeration of categories, each defining an predicated against a given roll is tested.

public Set<Category> possibleCategories() {
    return Stream.of(Category.values())
        .filter(category -> category.isPossibleCategoryFor(dice))

And here the definition of the single categories and the check if a dice matches the category:

enum Category {

    private Predicate<List<Dice>> rule;

    private Category(Predicate<List<Dice>> rule) {
        this.rule = rule;
    public boolean isPossibleCategoryFor(Dice dice) {
        return rule.test(dice);

Of course you could implement something like this with earlier Java versions as well. Only the method implementations are different.

Here I struggled again, when I wrote the method creating possible straights:

private static Set<Set<Dice>> possibleStraights(int numberOfDice) {
    return IntStream.range(0, Dice.values().length - numberOfDice)
        .mapToObj(startDice -> IntStream.range(startDice, startDice + numberOfDice)
            .mapToObj(die -> Dice.values()[die]).collect(Collectors.toSet()))

I fear everyone of you thought “WTF?” at the first sight. Although I chose an self-explanatory name (at least I hope so), it’s not clear, what the code does. You may hope, that it really creates a set of possible straights. But after I extract a method it seems more readable again.

private static Set<Set<Dice>> possibleStraights(int numberOfDice) {
    return IntStream.range(0, Dice.values().length - numberOfDice)
        .mapToObj(startDice -> createStraightStartingAt(startDice, numberOfDice))

private static Set<Dice> createStraightStartingAt(int startDice, int numberOfDice) {
    return IntStream.range(startDice, startDice + numberOfDice)
        .mapToObj(die -> Dice.values()[die]).collect(Collectors.toSet());

You can find the code on GitHub.


I really think my feeling that the Java 8 code is less readable and maintainable, is just because these Java syntax is quite new. (And maybe I don’t trust other developers, that they are familiar with these new features.)

I am quite sure, that the code is as easy to read and maintain as the “old-fashioned” java style. And in a few month it will be completely common. But we should always think twice, if streams and lambdas are the best possible solution for our problem. Just because we have a hammer, not everything is a nail.

But what do you think? Do you think the code is less cleaner because of the Java 8 syntax?