For Episode 67 of the Java Series:
interface ISmellElephants{
boolean elephante(int a, int b);
}
//Generic Functional Interface
interface ISmellDemons<X>{
int doSomething(X[] array, X a); //Method that takes an array and a variable(both same type)
}
//Functional Interface that uses a constructor
interface ISmellCows{
Cow doCowFunc(int a);
}
//A class that will hold our static method
class ElephantClass{
static boolean elephanteMethod(int a, int b){
if (a > b){
return true;
}else{
return false;
}
}
}
//Class to hold the instance method
class Fart{
boolean isLesser(int a, int b){
if(a < b){
return true;
}else{
return false;
}
}
}
//Class that holds our generic method implementation
class DemonClass{
static <X> int countNumOfMatched(X[] array, X a){ //method that takes an array and a number that searches that array for that number and returns the amount of times that number is found in the array
int num = 0; //Number of matched variables in array
for (int i = 0;i < array.length;i++){
if (array[i] == a){
num++;
}
}
return num;
}
}
//Class that holds our constructors and stuff
class Cow{
int number;
Cow(int a){ //Constructor that will hook into the functional interface because the interface takes a parameter
number = a;
}
Cow(){
number = 0;
}
int getCowNumber(){
return number;
}
}
public class Main {
public static void main(String[] args){
// ISmellElephants y33t = (int a, int b) -> {
// return ElephantClass.elephanteMethod(a, b);
// };
ISmellElephants y33t = ElephantClass::elephanteMethod; //This line is a simplification for the line above
System.out.println(y33t.elephante(5, 3));
//Instead of directly using a lambda to provide the implementation for our functional interface,
//we plug in a statis method reference that serves as our lambda expression, like we might do with
//lambda object reference
boolean result = anotherMethod(ElephantClass::elephanteMethod, 24, 1);
System.out.println(result);
//Example with an instance method
Fart yummyfart = new Fart();
boolean result2 = anotherMethod(yummyfart::isLesser, 7, 6); //Notice we use the object in front of the method name this time because its not a static method anymore
System.out.println(result2);
//An example with a generic method
String[] stringsArray = {"yes", "no", "booty", "no", "yes", "yes"};
Integer[] integersArray = {1, 4, 1, 4, 1, 5, 2, 12, 1231};
int matches1 = anotherAnotherMethod(DemonClass::<String>countNumOfMatched, stringsArray, "yes");
System.out.println(matches1);
int matches2 = anotherAnotherMethod(DemonClass::<Integer>countNumOfMatched, integersArray, 11);
System.out.println(matches2);
//Finally, an example using a constructor
ISmellCows cows = Cow::new; //Constructor Reference. The abstract method and constructor are now linked
Cow cowObject = cows.doCowFunc(20); //Running the constructor and creating an object by calling upon the functional interface method
System.out.println(cowObject.getCowNumber()); //Calling the method within the Cow class
}
//Here is an example of a method that takes a lambda as a parameter
static boolean anotherMethod(ISmellElephants elephantInterface, int a, int b){
return elephantInterface.elephante(a, b);
}
//Method using our generic functional interface as a parameter
static <X> int anotherAnotherMethod(ISmellDemons<X> demonInterface, X[] array, X a){
return demonInterface.doSomething(array, a);
}
}