Showing posts with label Java 8. Show all posts
Showing posts with label Java 8. Show all posts

Friday, February 11, 2022

Clean code - Optional comparison

Following is an example of writing less verbose and clean code for optional value comparison. This code (isAbc2) avoids unnecessary IF condition. The code sample also has a way to compare clean code and legacy code for a safety.


import java.util.Optional;

public class C1 {
	public static void main(String[] arg) {
		Optional val = Optional.of("abc");
		Optional noval = Optional.empty();
		Optional def = Optional.of("def");
		
		System.out.println(isAbc1(val) == isAbc2(val));
		System.out.println(isAbc1(noval) == isAbc2(noval));
		System.out.println(isAbc1(def) == isAbc2(def));
		
	}
	
	private static boolean isAbc1(Optional op) {
		if(op.isPresent()) {
			return op.get().equals("abc");
		}
		return false;
	}

	// clean code
	private static boolean isAbc2(Optional op) {
		return op.map("abc"::equals).orElse(false);
	}
}


The result of the above code in JDK 11.

true
true
true

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;
        }
    }
    
}
  

Sunday, August 20, 2017

Java stream: Logging before filter

While iterating in Java Streams, we may need to log all the items processed by the stream. Especially when using filter in the stream. We can use Peek api for achieving the same.

The following ready to run code will help try out.

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class LogStream {
    public static void main(String[] args) {
        System.out.println("Log");
        List result = data().stream()
                .peek(e -> System.out.println(e.getSalary()))
                .filter(e -> e.getSalary()
                        .doubleValue() < 2)
                .collect(Collectors.toList());
        System.out.println("Result");
        result.forEach(e -> System.out.println(e.getSalary()));
    }
    
    static class Emp {
        public Emp(String name, String dept, BigDecimal salary) {
            super();
            this.name = name;
            this.dept = dept;
            this.salary = salary;
        }
        
        private String name;
        private String dept;
        private BigDecimal salary;
        
        public String getName() {
            return name;
        }
        
        public String getDept() {
            return dept;
        }
        
        public BigDecimal getSalary() {
            return salary;
        }
    }
    
    private static List data() {
        Emp e1 = new Emp("e1", "dept1", BigDecimal.valueOf(1.1));
        Emp e2 = new Emp("e2", "dept1", BigDecimal.valueOf(1.1));
        Emp e3 = new Emp("e3", "dept2", BigDecimal.valueOf(2.1));
        Emp e4 = new Emp("e4", "dept2", BigDecimal.valueOf(1.9));
        return Arrays.asList(e1, e2, e3, e4);
    }
    
}