Practical Functional Java

Function Composition

Jeff Butler

https://github.com/jeffgbutler/practical-functional-java

https://jeffgbutler.github.io/practical-functional-java/

Function Composition

Higher Order Functions in Java

All code examples in examples.basics.composition.FunctionCompositionTest.java

Higher Order Functions

  • Higher order functions means that functions can be used as parameters, return values, or attributes
  • Java doesn't have functions/methods that live outside of objects
  • Functional interfaces and lambdas have added some syntax support
  • This topic can get crazy with weird vocabulary and unusual concepts
  • We're going to cover something relatively simple that will be useful later on

BiFunction Functional Interface

          
    // create a basic concatenation function
    private BiFunction<String, String, String> concat = (a, b) -> a + " " + b;

    @Test
    public void testConcat() {
        String phrase = concat.apply("Hello", "Fred");
        
        assertThat(phrase).isEqualTo("Hello Fred");
    }
          
        

Function and BiFunction Functional Interfaces

          
    // create a basic concatenation function
    private BiFunction<String, String, String> concat = (a, b) -> a + " " + b;
    
    // create a new function that calls the concatenation function, but
    // provides the first parameter as a constant
    private Function<String, String> hello = a -> concat.apply("Hello", a);

    @Test
    public void testHello() {
        String phrase = hello.apply("Fred");
        
        assertThat(phrase).isEqualTo("Hello Fred");
    }
          
        

"composed" Functions are Useful in Stream Pipelines

          
    // create a basic concatenation function
    private BiFunction<String, String, String> concat = (a, b) -> a + " " + b;
    
    // create a new function that calls the concatenation function, but
    // provides the first parameter as a constant
    private Function<String, String> hello = a -> concat.apply("Hello", a);

    @Test
    public void testHelloInStream() {
        String answer = Stream.of(ImmutablePerson.of("Fred", "Flintstone"),
                                  ImmutablePerson.of("Barney", "Rubble"))
                .map(ImmutablePerson::getFirstName)
                .map(hello)
                .collect(Collectors.joining(", "));

        assertThat(answer).isEqualTo("Hello Fred, Hello Barney");
    }
          
        

Time to Code!

Refactor a Looping Mess