Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Benefit of using Java Function rather than normal method?

Tags:

java

java-8

The Function Interface is introduced in Java 8, to implement functional programming in Java. It represents a function that takes in one argument and produces a result. It's easy to practise and read, but I am still trying to understand the benefit of it other than just making it look cool. For example,

Function<Integer, Double> half = a -> a / 2.0;
Function<Double, Double> triple = b -> b * 3;
double result = half.andThen(triple).apply(8);

can just be converted as a standard method like

private Double half(int a) {
    return a / 2.0;
}
private Double triple (int b) {
    return b * 3;
}
double result = triple(half(8));

So what's the benefit of using Function? As it refers to functional programming, what exactly is functional programming in Java and benefit it could bring? Would it benefit the way like:

  1. execution of chaining functions together (e.g andThen & compose)
  2. usage inside Java Stream?
  3. the access modifier as function tends to define with private not public, while method can be either?

Basically, I'm curious to know, in what circumstances would we prefer using function rather than normal method? Is there any use case that's unable or difficult to use, or converted with a normal method?

like image 622
Kev D. Avatar asked Aug 11 '21 03:08

Kev D.


People also ask

What is the difference between a method and a function Java?

A function in JavaScript is a statement that performs a task or calculates a value, takes in an input, and returns an output as a result of the relationship between the input. A method is a property of an object that contains a function definition. Methods are functions stored as object properties.

What is the need of functional programming in Java?

The basic objective of this style of programming is to make code more concise, less complex, more predictable, and easier to test compared to the legacy style of coding. Functional programming deals with certain key concepts such as pure function, immutable state, assignment-less programming etc.

What is the purpose of functional interface in Java?

Functional interfaces are included in Java SE 8 with Lambda expressions and Method references in order to make code more readable, clean, and straightforward. Functional interfaces are interfaces that ensure that they include precisely only one abstract method.


4 Answers

One usage of Function is in Streams. Everyone uses map method these days, I believe:

This map method accepts the Function as a parameter. This allows writing a pretty elegant code - something that could not be achieved before Java 8:

Stream.of("a", "b", "c")
   .map(s -> s.toUpperCase())
   .collect(Collectors.toList());
// List of A, B, C

Now its true that there are method references and functional interfaces (one of which is Function of course), this lets you using method reference to rewrite the above example as:

Stream.of("a", "b", "c")
    .map(String::toUpperCase)
    .collect(Collectors.toList())

... but that's only a syntactic sugar - map still accepts the Function as a parameter of course.

Another example that uses Function from Java itself is StackWalker: Here is an example:

List<StackFrame> frames = StackWalker.getInstance().walk(s ->
    s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
     .limit(10)
     .collect(Collectors.toList()));
}

Note the call to walk method - it accepts a function as a parameter.

So bottom line, it's just yet another tool that can help the programmer to express his/her intentions. Use it wisely wherever appropriate.

like image 88
Mark Bramnik Avatar answered Oct 16 '22 07:10

Mark Bramnik


Suppose I want to write an applyTwice function:

double applyTwice(double x, Function<Double, Double> f) {
  return f.apply(f.apply(x));
}

This needs the function be represented as an object.

Functions are useful when you want to put some structure around arbitrary code supplied by the caller.

like image 34
tgdavies Avatar answered Oct 16 '22 07:10

tgdavies


One example I had to use just a few days ago at my workplace is when I wanted to lazily compute a message, depending on a condition. For example imagine a logger usage like this:

  logger.debug("my-heavy-computed-message-here");

Now imagine that the computation of "my-heavy-computed-message-here" is really just that - it is heavy to compute; but you only want to present it if the DEBUG logger is enabled. What people usually do is:

if(logger.isDebugEnabled()) {
    logger.debug("my-heavy-computed-message-here");
}

This is ugly. Instead, we have some code in place that takes a Function (or Supplier) as input:

 logger.debug(Function<SomeObject, String> function)

Internally in our logger implementation we call function::apply (thus computing that expensive String) only as needed (or in a 'lazy' fashion).

like image 4
Eugene Avatar answered Oct 16 '22 08:10

Eugene


In Java it's usually called "pure functions", which are defined alike:

  • The execution of the function has no side effects.

  • The return value of the function depends only on the input parameters passed to the function.

Anything else should be an object's method.

like image 3
Martin Zeitler Avatar answered Oct 16 '22 07:10

Martin Zeitler