Thursday, February 11, 2021

Compact code with flatMap for methods returning Optional

Compact code with flatMap for methods returning Optional. flatMap() method is available both in Stream and Optional. flatMap method can help in writing compact code as shown below. Moreover several article suggest to avoid using get() in Optional. flatMap() can also help in avoiding get() as shown below.



import java.util.List;
import java.util.Optional;

public class OpMap {
    
    public static void main(String[] arg) {
        Emp emp = new Emp();
        
        String dname = emp.getDept()
                .map(Dept::getName)
                .orElse("temp");
        System.out.println(dname);
        
        dname = emp.getDept()
                .map(Dept::getOptionalName)
                .orElse(Optional.empty()) // This is bad
                .orElse("temp");
        System.out.println(dname);
        
        dname = emp.getDept()
                .map(Dept::getOptionalName)
                .filter(Optional::isPresent) // This is bad
                .map(Optional::get) // This is bad
                .orElse("temp");
        System.out.println(dname);
        
        dname = emp.getDept()
                .flatMap(Dept::getOptionalName) // Better option
                .orElse("temp");
        System.out.println(dname);
        
        List emps = List.of(new Emp());
        dname = emps.stream()
                .map(Emp::getDept)
                .filter(Optional::isPresent) // This is bad  
                .map(Optional::get) // This is bad
                .map(Dept::getOptionalName)
                .filter(Optional::isPresent) // This is bad
                .map(Optional::get) // This is bad
                .findFirst().orElse("temp");
        System.out.println(dname);
        
        dname = emps.stream()
                .map(Emp::getDept)
                .flatMap(Optional::stream) // Better option
                .map(Dept::getOptionalName)
                .flatMap(Optional::stream) // Better option
                .findFirst().orElse("temp");
        System.out.println(dname);
                
    }
    
    static class Emp {
        private String eName;
        private Dept dept;
        
        public Optional geteName() {
            return Optional.ofNullable(eName);
        }
        
        public void seteName(String eName) {
            this.eName = eName;
        }
        
        public Optional getDept() {
            return Optional.ofNullable(dept);
        }
        
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    }
    
    static class Dept {
        private String dName;
        
        public String getName() {
            return dName;
        }
        
        public Optional getOptionalName() {
            return Optional.ofNullable(dName);
        }
        
        public void setdName(String dName) {
            this.dName = dName;
        }
    }
    
}