Skip to main content

Posts

Showing posts with the label Functions

Java 8 - Functions - Function Types - Supplier

A Supplier is a function which returns an output without any input.
@Slf4j
public class Supplier_ {

    static Supplier<Person> personSupplier = () -> new Person("Tom", "Smith");

    public static void main(String[] args) {
      log.info("supplied person is " + personSupplier.get());
    }

}

Java 8 - Functions - Function Types - Predicate

A Predicate is a function which acts on an input to return a boolean.A Predicate can be transformed to its negated value using negatePredicates can be composed using and and or.
@Slf4j
public class Predicate_ {

   static Function<String, Boolean> normalPredicateFunc = s -> s.length() > 0;
   static Predicate<String> nonEmptyString = s -> s.length() > 0;

   static Predicate<String> emptyString = nonEmptyString.negate();

   static Predicate<String> correctLength = nonEmptyString.and(s -> s.length() > 2);
   static Predicate<String> validString = correctLength.or(nonEmptyString);

   public static void main(String[] args) {
     log.info("predicates match: " + (nonEmptyString.test("hi") == normalPredicateFunc.apply("hi")));

     log.info("string is empty: " + emptyString.test(""));

     log.info("string is valid: "…

Java 8 - Functions - Function Types - Identity Function

An Identity function is a function which returns it's input as output.

@Slf4j
public class IdentityFunction {

   static Function<Integer, Integer> identifyFunc = x -> x;
   static Function<Integer, Integer> identifyFunc2 = Function.identity();
   static Function<Integer, Integer> identifyFunc3 = UnaryOperator.identity();

   public static void main(String[] args) {
     log.info("identify function input matches output: " + (identifyFunc.apply(1) == 1));
     log.info("second identify function input matches output: " + (identifyFunc2.apply(2) == 2));
     log.info("third identity function input matches output: " + (identifyFunc3.apply(3) == 3));
   }
}


Java 8 - Functions - Function Types - Primitive Args Functions

There are cases when the performance cost of auto boxing is significant.When dealing with a lot of primitive values, avoid auto boxing by creating lambdas that use primitives.The examples shown below use int primitive type, but there are corresponding versions for the double and long primitive types, just replace Int with Double or Long.
@Slf4j
public class FunctionsWithPrimitiveArgs {

    /*
     function to convert int to any type
    */
    IntFunction<String> intToString = i -> Integer.toString(i);

    /*
     function to convert any type to int
    */
    ToIntFunction<String> parseInt = str -> Integer.valueOf(str);

    /*
     function that takes an int to return a boolean i.e a Predicate accepting int input
    */
    IntPredicate isEven = i -> i % 2 == 0;

    /*
     function that takes two inputs to return an int
    */
    ToIntBiFunction<String,String> maxLength = (left, right…

Java 8 - Functions - Function Types - Function

A Function acts on an input and returns an output.A UnaryOperator is a function whose input and output are of the same type.A BiFunction is a function which acts on two inputs and returns an output.A BinaryOperator is a BiFunction whose input and output are of the same type.BinaryOperator.minBy and BinaryOperator.maxBy return a BinaryOperator which calculate min and max values of two inputs.
@Slf4j
public class Function_ {

   static Function<Integer, Integer> incrementFunction = input -> input+1;
   static UnaryOperator<Integer> incrementFunction_2 = input -> input+1;

   static BiFunction<String, Integer, String> biFunction = (a, b) -> a + b;
   static BinaryOperator<String> concatFunction = (a, b) -> a + b;

   static BinaryOperator<Integer> max = BinaryOperator.maxBy((a,b) -> a.compareTo(b));
   static BinaryOperator<Integer> min = BinaryOperator.minBy((a,b) -> a-b);

   public static void main(Strin…

Java 8 - Functions - Function Types - Consumer

A Consumer is a function which takes an input and returns no output.A BiConsumer is a Consumer which accepts two inputs.
@Slf4j
public class Consumer_ {

   static Consumer<Person> greeter = person -> log.info("Hello, " + person.getFirstName());

   static Consumer<Iterable> printObjects = list -> list.forEach(item -> log.info(item.toString()));

   static BiConsumer<String, String> stringBiConsumer = (input1, input2) -> log.info(input1 + " " + input2);

   public static void main(String[] args) {
     greeter.accept(new Person("Tom", "Smith"));
     printObjects.accept(Arrays.asList("one", "two", "three"));
     stringBiConsumer.accept("log1", "log2");
   }

}

Java 8 - Functions - Function Types - Comparator

The Comparator function implements the Comparator interface, which is a Functional Interface.
@Slf4j
public class Comparator_ {

   static Comparator<Person> orderByFirstNameAsc = (p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName());
   static Comparator<Person> orderByFirstNameDesc = (p1, p2) -> p2.getFirstName().compareTo(p1.getFirstName());

   public static void main(String[] args) {
     Person person1 = new Person("adam", "smith");
     Person person1_clone = new Person("adam", "smith");
     Person person2 = new Person("paul", "robins");

     log.info("adam before paul in asc order: " + (orderByFirstNameAsc.compare(person1, person2) < 0));

     log.info("adam has same position with adam: " + (orderByFirstNameAsc.compare(person1, person1_clone) == 0));

    …

Java 8 - Functions - Higher Order Function

A Higher Order Function (HOF) is one whose input and/or output is a function.
@Slf4j
public class HigherOrderFunction {

   static BiFunction<Function<Person, Person>, Person, String> inputOnlyHOF = (personFunction, p) -> personFunction.apply(p).getFirstName();

   static Function<Person, Function<Person, Person>> outputOnlyHOF = person -> ( p -> new Person(p.getFirstName()+person.getFirstName(), p.getLastName()+person.getLastName()) );

   public static void main(String[] args) {

     log.info("inputOnlyHOF: " + inputOnlyHOF.apply(p -> new Person(p.getFirstName()+"s", p.getLastName()), new Person("Tom", "Cruise")) );

     log.info("outputOnlyHOF: " + outputOnlyHOF .apply(new Person("Tom", "Cruise")) .apply(new Person("Ben", &…

Java 8 - Functions - Functional Interface

All Java functions implement the FunctionalInterface interface.A functional interface must contain exactly one abstract method declaration, but any number of default and static methods.The @FunctionalInterface annotation can be omitted when creating a functional interface.

@Slf4j
public class FunctionalInterface_ {

   @FunctionalInterface
   interface Dog {
     String bark(Person person);
   }

   public static void main(String[] args) {
     Dog dog = person -> "Bark at " + person.getFirstName();

     log.info(dog.bark(new Person("Tom", "Smith")));
   }

}

Java 8 - Functions - Composition

Often it makes sense to chain functions, such that the output of a function is fed into another function.fncB(fncA) can be implemented using 'andThen' and 'compose' keywords.apply fncA andThen apply fncB, i.e. fncA.andThen(fncB)apply fncB but first compose fncA i.e. fnB.compose(fncA)

@Slf4j
public class FunctionComposition {

   static Function<Person, String> eat = person -> person.getFirstName() + " is eating";

   static Function<String, String> personStatus = UnaryOperator.identity();

   public static void main(String[] args) {

     Person person = new Person("Tom", "Cruise");

     log.info("andThen: " + eat.andThen(personStatus).apply(person));
     log.info("compose: " + personStatus.compose(eat).apply(person));

   }
}


Java 8 - Functions - Currying

Sometimes, all inputs to a function are not available at the time of function application.Thus, we can apply only the available inputs, and then return a function which can be applied to the remaining inputs, whenever those remaining inputs are available.A curried function is one which can accept partial inputs.Currying is the process of making an un-curried function curried.
@Slf4j
public class Currying {

   static BiFunction<String, String, String> uncurried = (a, b) -> "Hello " + a + b;

   static Function<String, Function<String, String>> curried = a -> (b -> "Hello " + a + b);

   public static void main(String[] args) {
     log.info("uncurried function output: " + uncurried.apply("Tom", "Cruise"));

     Function<String, String> partiallyAppliedFunction = curried.apply("Tom");

     log.info("finally, curried function output: " + partiallyA…

Java 8 - Functions - Constructor Reference

The constructor of a class can be converted to a function using the new keyword

@Slf4j
public class ConstructorReference {

   @Getter
   private final String member;

   ConstructorReference(String input) {
     member = input;
   }

   public static void main(String[] args) {
     Function<String, ConstructorReference> constructorRef = ConstructorReference :: new;

     log.info("member is: " + constructorRef.apply("Tom").getMember());
   }

}

Java 8 - Functions - Closure

Closure is a function whose operation is dependent on some variable in it's environment.Such function is said to have a side effect on its environment.Pure functions don't have side effects. The return value of a Pure Function is only determined by its input values, without observable side effects.

@Slf4j
public class Closure {

   private static int member = 0;

   static Consumer<Integer> closure = input -> member += input;
   static Consumer<Integer> pureFunction = input -> input += 1;

   public static void main(String[] args) {
     closure.accept(1);
     log.info("a closure has side effect: " + (member == 1));

     pureFunction.accept(1);
     log.info("pure function does not have side effect: " + (member == 1));
   }
}


Java 8 - Functions - Anonymous Function

Anonymous function (or Lambda) is a function without a reference variable.We use Lambdas when there is no need to store a reference to a function object, e.g. when passing a function as input parameter to a method or implementing a functional interface.
printer method which accepts a function void printer(String input, Consumer<String> stringConsumer) {
   stringConsumer.accept(input);
}

string to integer converter method
Integer stringToIntegerConverter(String input, Converter<String, Integer> converter) {
   return converter.convert(input);
}


functional interface with name Converter
@FunctionalInterface
interface Converter<F, T> {
   T convert(F from);
}


USAGE

passing an anonymous function as input parameter to printer method  printer("Tom", i -> log.info("Hello " + i));

implementing a functional interface using anonymous function
log.info("stringToIntegerConverter output: " + stringToIntegerConverter("…