Understand how functional programming was introduced to Java in one shot

Introduction

I got Java SE8 Gold, and now I can use the functional interface, lambda expression, and Stream API that occupied most of the questions, but what is it after all? It was in a state.

So, I decided to summarize why functional programming was introduced in the first place and how the idea of functional interfaces and lambda expressions was born. (~~ Summarize before taking the exam ~~)

Imperative programming and functional programming

Java has endorsed imperative programming!

Suddenly, take a look at the code below.

  public static void findMatsumoto(List<String> names) {

    boolean found = false;

    for (String name : names) {
      if (name.equals("Matsumoto")) {
        found = true;
        break;
      }
    }
     
    if (found)
      System.out.println("Found Matsumoto");
    else
      System.out.println("Sorry, Matsumoto not found");
  }

It's a very simple method. The names list passed as an argument is looped element by element to check if it matches Matsumoto. If there is an element that matches Matsumoto, set the local variable found prepared in advance to true and exit the loop. Finally, if found is true, "found Matsumoto" is displayed, and if false, "Sorry, Matsumoto not found" is displayed.

As mentioned above, this method is written in so-called "** imperative programming **" which defines all the steps of repeating each element, comparing values, setting flags, and exiting the loop. I will.

What happens if you try to write it in functional programming?

If you try to describe the method of ↑ by functional programming, it will be as follows.

public static void findMatsumoto(List<String> names) {

  if (names.contains("Matsumoto"))
    System.out.println("Found Matsumoto");
  else
    System.out.println("Sorry, Matsumoto not found");

}

It's much cleaner than imperative programming, isn't it? In particular, the functional type does not describe loop processing. The contains method takes care of everything, and the developer has nothing to do with how it's handled. However, you can get the expected result with just this description.

In other words, if you write it in functional programming, you can make the code ** simpler and easier to understand ** than in imperative programming.

★ References [1] [Shortcut to transition to functional programming-Introducing functional methods into Java programs with declarative thinking-](https://www.ibm.com/developerworks/jp/java/library/j- java8idioms1 / index.html)

There are many other benefits of functional programming!

Besides making the code concise and easy to understand, functional programming has many benefits.

In functional programming, functions have the following properties. ** ● Always returns the same result for the entered value ** ** ● Function evaluation has no effect on others **

The following methods can be called functions.

public int add(int x, int y) {

  return x + y;

}

It always returns the same result for the inputs (x and y), and the evaluation here has no other effect.

On the other hand, can the following methods be called functions?

public int add(int y) {

  return x += y; //x is a variable defined outside the method

}

This method does not always return the same result for input y. (Depends on the external variable x.) It also affects the external variable x. From the above, this method cannot be called a function.

Due to the above properties, the following merits can be considered by using the function. ** 1. Easy to test ** You only need to consider one test case, as the same result will always be returned for the value you enter.

** 2. Highly safe ** The evaluation by the function has no effect on others, so it is very safe without any unexpected changes.

** 3. Streamline parallel processing ** It is suitable for parallel processing because the functions do not depend on each other. In recent years, the improvement of single core performance has slowed down, and the CPU architecture tends to be multi-core with more cores. It is expected to fit this multi-core trend by using functions. In other words, parallel processing can be made more efficient and processing speed can be improved.

Notable properties of functional programming

In addition, there are two notable properties of functional programming: ** ● You can pass a function as a function argument ** ** ● You can pass a function to the return value of a function **

I would like to show a concrete example using "** Haskell **" which is famous as a functional programming language.

The following is a program that outputs the total value of the elements of the array.

haskell


ary = [ 1, 3, 5, 7, 9 ]
main = print $ foldl (+) 0 ary

The (+) function is passed as the first argument of a function called foldl. Returns the total value of the elements of the array ary passed in the third argument, with 0 as the initial value in the second argument. You can see that it is written very concisely.

If you try to do the same thing in Java,

Java



public static int addAll(int[] ary) {

    int total = 0;

    for (int i : ary) {
        total += i;
    }

    return total;
}

public static void main(String[] args) {
    int[] ary = { 1, 3, 5, 7, 9 };
    System.out.println(addAll(ary));
}

It will be. Since I'm writing a loop, the code is a bit long.

If you use functional programming, you can describe the process of displaying the elements of an array on the console in ** only one line **, so the difference in the amount of description is obvious.

****** So far, I've only covered the benefits of functional programming, but I'm not blindly thinking that functional programming is the best !!! ** To clarify the background ** Only the benefits are taken up. The superiority and inferiority of functional programming, imperative programming, and procedural programming are beyond the scope of this paper and will not be discussed. (Sometimes I'm not so familiar with functional programming that I can discuss it myself.)

★ References [2] Let's go with functional programming ~ The entrance to the functional entrance that everyone loves from Java [3] Let's know the power of functional programming-Part 2

If there are so many benefits, you should introduce functional programming even in Java!

I've written it for a long time so far, but to summarize it briefly, functional programming has many advantages, and let's introduce it to Java! It became. However, although it has great merits, it was not simple due to issues at the same time.

Problems in incorporating the essence of functional programming into Java

As you can see from the nature of functions in functional programming, "You can pass a function as an argument to a function", please be aware that "function in functional programming" = "method".

To elaborate a little more, functional programming treats a function as a first-class citizen, so you can pass a function as a function argument, but since a first-class object in Java is a class, ** a method is used as a method argument. It cannot be passed **.

Appearance of "functional interface"

As mentioned above, Java does not allow you to pass a method as a method argument. However, if it is an object (instance), you can pass it as an argument!

So, then I made a ** function-like object ! Then, " functional interface **" was devised.

What is a functional interface?

It is a "functional interface" created as a function-like object, but its definition is as follows.

** ● Interface with a single abstract method (SAM interface) **

Specific example of functional interface

@FunctionalInterface
public interface Example {
    public int calc(int x);      //Abstract method (SAM)
    static void say() { }        //static method
    default void hello() { }     //default method
    public String toString();    //Public method of Object class
}

This is a functional interface!



**e? ** **

Where is it like a function? I think I felt that. Well, it's understandable by using it, so let's actually write a program.

When passing a function object (functional interface) as a method argument, use the notation of "** anonymous inner class **". For more information on anonymous inner classes, see [4].

//Functional interface
@FunctionalInterface
public interface Calc {
    public int add(int x, int y);    //Abstract method (SAM)
}

//Implementation of print method with Calc as an argument
private void print(int x, int y, Calc c) {
    System.out.println(c.add(x, y));
}

//Call the print method
print(3, 4, new Calc() {
    @Override
    public int add(int x, int y) {
        return x + y;
    }
});

//Execution result 7

As mentioned above, by using the anonymous inner class, it is possible to instantiate the functional interface Calc, implement the abstract method add, and pass it to the argument of the print method.



**e? ** **

The amount of description is not small at all, and it doesn't feel like functional programming! !!

That's right. This is where the "** lambda expression **" comes into play.

★ References [4] Anonymous Inner Class [5] Introduction to Java8 Lambda [6] Functional Interfaces-Learn how to create custom functional interfaces and why you should always use built-in functional interfaces when possible- /java/library/j-java8idioms7/index.html)

When I write it in a lambda expression ...

What is a lambda expression?

A lambda expression is a notation that simplifies the instantiation of a class that implements an abstract method of a functional interface (which was done earlier in the anonymous inner class).

Let's see how to omit it concretely. (1) First, it is obvious from the type inference of the compiler that the type of the variable that can be passed to the third argument of the print method is a Calc type object, so "new Calc () {}" can be omitted.

(2) Furthermore, since the Calc interface is a functional interface, there is only one abstract method, so it is obvious to override and implement it, so "@ Override public int add" can also be omitted.

(3) Finally, the argument type is also obvious by type inference, so it can be omitted, and if the method block ({}) is omitted, the return keyword can also be omitted (in this case, return cannot be described rather than omitted). Based on the above, the above call to the print method can be rewritten as follows.

//Call the print method
print(3, 4, (x, y) -> x + y);

Oh, it's really short! What we are doing is the same as in the case of the anonymous inner class, we are implementing the method add that performs addition and instantiating the class, but the description of the new operator and method override that is usually required for instantiation is It's abbreviated, so it's very concise, and it looks like you're passing a ** function (method) that does the addition directly to the method's arguments **.

That's right! !! In other words, ** code written simplified using lambda expressions looks like functional programming **!

Master the lambda expression

You've found that you can introduce functional programming by using a combination of functional interfaces and lambda expressions.

And Java8's java.util.function package provides a general-purpose functional interface, and the java.util.stream package is an API for processing data in a pipeline format, with a functional interface as an argument. There are many methods to take. Of course, you can also create a custom functional interface.

The following program displays the names of men in the names list.

names.stream().filter(n -> n.getSex() == 0)
    .map(n -> n.getName())
    .forEach(System.out::println);

Isn't it easy to read and concise? In this way, you can introduce functional programming by skillfully combining functional interfaces with lambda expressions, built-in functional interfaces, and Stream APIs.

I would like to summarize the java.util.function package and Stream API in a separate article.

★ References [7] [Thorough Strategy Java SE 8 Gold Problem Collection](https://www.amazon.co.jp/ Thorough Strategy-Java-Gold-Problem Collection-1Z0-809 / dp / 4295000035 / ref = sr_1_2? S = books & ie = UTF8 & qid = 1538986245 & sr = 1-2 & keywords = java + gold + se8) [8] Understanding Java 8 lambda expressions

Summary

Since functional programming has many merits, I would like to introduce it to Java as well.   ↓ By preparing an object (functional interface) that has only one abstract class instead of a function and simplifying the instantiation of the class using a lambda expression, we were able to introduce functional programming to Java! !!

Recommended Posts

Understand how functional programming was introduced to Java in one shot
~ I tried to learn functional programming in Java now ~
How to master programming in 3 months
Introduction to Functional Programming (Java, Javascript)
How to learn JAVA in 7 days
How to use classes in Java?
How to name variables in Java
How to concatenate strings in java
How to increment the value of Map in one line in Java
How to implement date calculation in Java
How to implement Kalman filter in Java
Multilingual Locale in Java How to use Locale
Java reference to understand in the figure
How to do base conversion in Java
How to implement coding conventions in Java
How to embed Janus Graph in Java
How to get the date in java
Understand in 5 minutes !! How to use Docker
How to use credentials.yml.enc introduced in Rails 5.2
How to display a web page in Java
How to get Class from Element in Java
How to hide null fields in response in Java
[Java] How to substitute Model Mapper in Jackson
How to solve an Expression Problem in Java
How to write Java String # getBytes in Kotlin?
Contemplation: How to take advantage of functional interfaces in your own functions (java)
How to call functions in bulk with Java reflection
How to create a Java environment in just 3 seconds
[Java] How to omit the private constructor in Lombok
How to input / output IBM mainframe files in Java?
Understand how to use Swift's JSON Decoder in 3 minutes
How to create a data URI (base64) in Java
Java classes and instances to understand in the figure
How to generate / verify ID token in Java Memo
How to convert A to a and a to A using AND and OR in Java
How to convert a file to a byte array in Java
How to Git manage Java EE projects in Eclipse
Summary of how to implement default arguments in Java
How to put old Java (8 series) in macOS 10.15 Catalina
Notes on how to use regular expressions in Java
How to batch initialize arrays in Java that I didn't know when I was a beginner
How to get the class name / method name running in Java
How to read your own YAML file (*****. Yml) in Java
How to use JSON data in WebSocket communication (Java, JavaScript)
Memo: [Java] How to check groupId etc. described in pom.xml
How to store a string from ArrayList to String in Java (Personal)
What happened in "Java 8 to Java 11" and how to build an environment
How to call and use API in Java (Spring Boot)
How to use Java enums (Enum) in MyBatis Mapper XML
How to dynamically switch JDK when building Java in Gradle
How to develop and register a Sota app in Java
How to simulate uploading a post-object form to OSS in Java
How to deploy Java application to Alibaba Cloud EDAS in Eclipse
How to derive the last day of the month in Java
Differences in how to handle strings between Java and Perl
An introduction to functional programming for object-oriented programmers in Elm
How to switch Java in the OpenJDK era on Mac
[Java] How to use Map
How to lower java version
[Java] How to use Map
How to uninstall Java 8 (Mac)