javajava-8functional-programmingvavrdeclarative-programming

Java Functional Programming: How to convert a if-else ladder inside for loop to functional style?


The expectation is derive 3 lists itemIsBoth, aItems, bItems from the input list items. How to convert code like below to functional style? (I understand this code is clear enough in an imperative style, but I want to know does declarative style really fail to deal with such a simple example). Thanks.

for (Item item: items) {
    if (item.isA() && item.isB()) {
        itemIsBoth.add(item);
    } else if (item.isA()) {
        aItems.add(item);
    } else if (item.isB()){
        bItems.add(item)
    }
}

Solution

  • The question title is quite broad (convert if-else ladder), but since the actual question asks about a specific scenario, let me offer a sample that can at least illustrate what can be done.

    Because the if-else structure creates three distinct lists based on a predicate applied to the item, we can express this behavior more declaratively as a grouping operation. The only extra needed to make this work out of the box would be to collapse the multiple Boolean predicates using a tagging object. For example:

    class Item {
        enum Category {A, B, AB}
    
        public Category getCategory() {
            return /* ... */;
        }
    }
    

    Then the logic can be expressed simply as:

    Map<Item.Category, List<Item>> categorized = 
        items.stream().collect(Collectors.groupingBy(Item::getCategory));
    

    where each list can be retrieved from the map given its category.

    If it's not possible to change class Item, the same effect can be achieved by moving the enum declaration and the categorization method outsize the Item class (the method would become a static method).