How to Use Enum With Java 8 Lambda & Method References

  • Post last modified:December 15, 2022
  • Reading time:4 mins read

Introduction

Lambda and method references were one of the coolest features that were added when java 8 released and since its launch developer loved and started using it either in their POC or later in their production projects. In this article we will see with the help enum, lambda and later Method references how can we make our code loosely coupled and easier to maintain and modify.

Lambda Expression & Enum

Enum were released in Java 5 as special java type whose values are defined before hand as constants. We should use enum when we know the accepted value for the type. For example, if we know the accepted payment methods are cash, credit card, debit card , we can define them as enum, which gives compiler an understanding that accepted value for enum type is one of the defined values.

Lambda introduced in Java 8 in order to introduce much awaited functional programming paradigm into Java world. By using Lambda code we can write concise and less verbose code.Many time the code is 1 liner. Method reference is further improvement over lambda for certain cases such as method Invokation that do not return anything. Let’s use these two great java features to create java code that provides file reader logic based on file type.

Creating Enum File Type

We will first create enum class called FileType that will include constants such as CSV, EXCEL,PDF,FIXED_LENGTH. Lets add FileReaderService caller as Constructor argument for enum type.
We are calling respective reader class using method reference as ::.

Argument that we passing to constructor is BiConsumer that takes two input and doesnt return any output. First input is FileReaderService and second is the name of file to read from.

enum FileType {
        CSV(FileReaderService::readCSVFile),
        EXCEL(FileReaderService::readExcelFile),
        FIXED_LENGTH(FileReaderService::readFixedLengthFile),
        PDF(FileReaderService::readPDFFile);

        BiConsumer<FileReaderService, String> readerLogic;

        FileType(BiConsumer<FileReaderService, String> readerLogic) {
            this.readerLogic = readerLogic;
        }
}

Creating FileReader Service

Now lets create FileReaderService class that has methods to read various file such as readCSV, readExcel etc that takes fileName as input argument.

readFile method is invoked from client code and Neccessary FileType and filename is passed.
Filetype readerLogic BiConsumer accepts FileType and fileName as two argument and executes the necessary file read method based on passed fileType .

public class FileReaderService {

    public void readFile(FileType fileType, String fileName){
        fileType.readerLogic.accept(this,fileName);
    }

    public void readCSVFile(String fileName){
        try (FileReader fileReader = new FileReader(fileName)) {
            OpenCSVReader.readOneByOne(fileReader);
        }catch (Exception ex){
            System.out.println("Error Reading File"); // need error handling operation
        }
    }

    public void readExcelFile(String fileName){
       //todo
    }

    public void readPDFFile(String fileName){
        //todo
    }

    public void readFixedLengthFile(String fileName){
        //todo
    }

Client Code

Now In Our client code we can pass FileType as argument and full path of input file that we wish to read from. Since passed fileType is CSV, readLogic BiConsumer function will execute readCSVFile method from FileReader service.

 new FileReaderService()
                .readFile(FileType.CSV,
                 INPUT_FILE);

Loose Coupled Design

Our Infrastructure code , client code and logic is not tightly coupled and if we need to add new enum type for other file we can extend respective class without much hassle. For example if we new developer adds fileType called JSON, he can add that into enum Type, but now code will not compile until he provides the readerLogic for the new enum type. If we had enum without lambda as argument , in that case if some new developers add new file type and don’t implement logic to read it , compiler would not have throw error, but in our case it will quickly throw error to add reader logic.

and Now in the client code we can easily pass the file type as JSON along with fileName.

Hence our code is extensible and it is not tightly coupled.

Conclusion

In this article we discussed how can we write loosely coupled, extensible and concise code using java 8 lambda/method reference and enum.

Bonus Tip

Further Resources

Leave a Reply