Social Media

Category Archives for Java8

Another Java Lamdba Post

The syntax of a lambda is simple –

(parameters) -> expression
(parameters) -> { statements; }

Examples

Runnable r1 = () -> System.out.println("Hello World");

// or Streams
List winnersOfToursLessThan3500km = 
                           tdfWinners
                               .stream()
                               .filter(d -> d.getLengthKm() > 3500) // Separate out Tours less than 3500km
                               .map(Winner::getName) // Get names of winners
                               .collect(toList()); // Return a list

Key points are –

  • Concise – Before Java8 we would use anonymous classes to deliver “similar” functionality
  • Anonymous – no explicit name
  • Function – not associated with a particular class
  • Argument – can be passed as argument or Stored in a variable

Functional Interfaces

The key requirement for a lambda is that the interface it implements can only have a Single Abstract Method(SAM). However they can have any number of default and static methods

@FunctionalInterface Annotation

@FunctionalInterface is Optional, and enforces this rule by generating a compiler error –

Invalid '@FunctionalInterface' annotation; NotFunctionalInteface is not a functional interface

Java8 contains a number of useful interfaces in java.util.function –

Predicate   - boolean test(T t) - True/False condition on t
Consumer    - void accept(T t)  - Accepts t but returns no result
Function - R apply(T t)      - Takes t and returns an instance of R

Functional Descriptor

Describes the signature of the Functional Interface –

Predicate - t  -> boolean
Consumer  - t  -> void
Function  - t  -> R

Accessing Class Variables

  • final or “effectively final”(not changed after initialization)
        String finalString = "final string";
        String effectivelyFinalString = "effectively final string";
        Runnable r = () -> {
            System.out.println("Hi im " + finalString);
            System.out.println("Hi im " + effectivelyFinalString);
        };
        new Thread(r).start();

But trying to change effectivelyFinalString results stops it compiling –

       String finalString = "final string";
        String effectivelyFinalString = "effectively final string";
        Runnable r = () -> {
            System.out.println("Hi im " + finalString);
            System.out.println("Hi im " + effectivelyFinalString);
        };
        effectivelyFinalString = "now i wont compile";
        new Thread(r).start();

The reason this works is that the lambda is accessing a copy of the final or “effectively final” field.

Method References – ::

The final piece of the lambda jigsaw is Method References. Method references are simply a further shorthand in the body of the lambda – so where we have a lambda –

List winnersOfToursGreaterThan3500km = 
          tdfWinners
             .stream()
             .filter(d -> d.getLengthKm() >= 3500)
             .map(w -> w.getName())
             .collect(toList());

We see map has the lambda – w -> w.getName(). This represents this method –

 Stream map(Function mapper);

A method reference lets us shorthand that too –

List winnersOfToursGreaterThan3500km = 
          tdfWinners
             .stream()
             .filter(d -> d.getLengthKm() >= 3500)
             .map(W::getName)
             .collect(toList());

As with a lot of Java8 the purpose of this shorthand is to allow us to write cleaner more concise code

There are 4 types of method reference in Java 8 –

static method ContainingClass::staticMethodName
instance method of a particular object containingObject::instanceMethodName
instance method of an arbitrary object of a particular type ContainingType::methodName
constructor ClassName::new
1 7 8 9