In Java, Functional Interface is an interface with just one non-static abstract method, with an annotation @FunctionalInterface.

Configuration
Java Compilation:
Java Runtime:
JDK 11.0.12
JRE HotSpot 11.0.12
In Java, Functional Interface is an interface with just one non-static abstract method, with an annotation @FunctionalInterface
First, just create an interface MyFunctionalInterface.java:
@FunctionalInterface public interface MyFunctionalInterface { void run(); }
To use it, create an instance with Lambda expression to define the implementation:
public static void main(String[] args) { MyFunctionalInterface myFunctionalInterface = () -> { System.out.println("This is printing a statement"); }; myFunctionalInterface.run(); }
Output:
This is printing a statement
More likely and useful use is passing the Functional Interface as method argument so what the method should do could be decided at run time
Create another Functional Interface:
@FunctionalInterface public interface MyFunctionalInterface2<T, R> { R run(T t); }
This is an interface with 2 generic types. The function will take one argument and return a value
Create a normal class with a method which will take MyFunctionalInterface2 as argument to convert one String to another String:
public class MyClass { private List<String> words; public void setWords(List<String> words) { this.words = words; } public List<String> convert(MyFunctionalInterface2<String, String> myFunctionalInterface2) { List<String> list = new ArrayList<>(); for (String word : words) { list.add(myFunctionalInterface2.run(word)); } return list; } }
Some notes about MyClass.java:
  • Before calling the convert method, the setWords method has to be called to assign the value to the words
  • Both 2 types are String for MyFunctionalInterface2, which is used as the argument type in the convert method
  • The convert returns a new list of String from the original words by using the run method of MyFunctionalInterface2
To show the usage MyClass and MyFunctionalInterface2, first create a function to return the implementation of MyFunctionalInterface2<String, String>, then instantiate MyClass and call setWords to set the input, finally call convert by providing the implementation dynamically
The following shows 2 different implementations of MyFunctionalInterface2<String, String>
// Remove all the vowels, e.g. "apple" becomes "ppl" private static MyFunctionalInterface2<String, String> takeOutVowels() { return word -> word.replaceAll("[aeiou]", ""); }
and
// Remove all the letters which are duplicates e.g. "apple" becomes "ale" private static MyFunctionalInterface2<String, String> takeOutDuplicates() { return word -> { String wordWithoutDuplicates = ""; Map<Character, Integer> map = new HashMap<>(); for (char c : word.toCharArray()) { if (map.containsKey(c)) { map.put(c, map.get(c) + 1); } else { map.put(c, 1); } } for (char c : word.toCharArray()) { if (map.get(c) == 1) { wordWithoutDuplicates += c; } } return wordWithoutDuplicates; }; }
Main class:
public static void main(String[] args) { List<String> words = new ArrayList<>(); words.add("orange"); words.add("apple"); words.add("banana"); MyClass myClass = new MyClass(); myClass.setWords(words); System.out.println("Testing with takeOutVowels() returning MyFunctionalInterface2:"); // takeOutVowels() returns one kind of implementation of MyFunctionalInterface2 List<String> wordsWithoutVowels = myClass.convert(takeOutVowels()); for (String wordWithoutVowels : wordsWithoutVowels) { System.out.println(wordWithoutVowels); } System.out.println("Testing with takeOutDuplicates() returning MyFunctionalInterface2:"); // takeOutDuplicates() returns another kind of implementation of MyFunctionalInterface2 List<String> wordsWithoutDuplicates = myClass.convert(takeOutDuplicates()); for (String wordWithoutDuplicates : wordsWithoutDuplicates) { System.out.println(wordWithoutDuplicates); } }
Output:
Testing with takeOutVowels() returning MyFunctionalInterface2:
rng
ppl
bnn
Testing with takeOutDuplicates() returning MyFunctionalInterface2:
orange
ale
b