In today’s post, I’ll go through a primer of the different facilities that you can use.
Functional Interfaces
Single abstract method interfaces have been taken a step further in Java 8, where the programmer is able to decorate their interface using a @FunctionalInterface annotation. These can then be represented as lambda expressions and method references. These are building blocks for functional programming.
Consumer<T>
Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.
Scala’s type is very rich; even where constructs aren’t well defined you can easily piece together anything that you need. In today’s article, I’ll take you through some different functor types as well as a small primer on variance.
Variance
Type variance is what we use to describe sub-class relationships in a class hierarchy. In scala we use the following notations to denote variances:
Sometimes, you need to be able to look at the private members of your classes in order to test that something has gone to plan. Unit testing is one scenario where this makes sense.
By using the getDeclaredField method, passing the name of the field; the reflection framework will send back the definition. This field gets executed through the use of the get method, passing in the object instance.
To finish the picture here, we can also get access on methods that are private as well:
The functional programming paradigm has certainly seen a lot of attention of late, where some of the features that can be exploited from it have properties that assist in scale programming.
In today’s post, I’ll walk through Java 8 streams which allow you to treat collection data structures in a functional way.
What is a stream?
A stream prepares a collection of elements in such a way that you can operate on it functionally. The higher-order functions that you’d commonly see in a functional arrangement are:
Now that we have a basic structure of artists and songs, we can define some test data to work with.
Don’t judge me.
ArtistrickAstley=newArtist("Rick Astley",50,Arrays.asList(newSong("Never Gonna Give You Up",1987,500000)));ArtistbonJovi=newArtist("Jon Bon Jovi",54,Arrays.asList(newSong("Livin' on a Prayer",1986,3400000),newSong("Wanted Dead or Alive",1987,4000000)));List<Artist>artists=Arrays.asList(bonJovi,rickAstley);
Ok, now that the boilerplate is out of the way; we can start the fun stuff.
Map
map is a function that allows you to apply a function to each element of a list; transforming and returning it. We can grab just the artist’s names with the following:
toList comes out of the java.util.stream.Collectors class. So you can import static:
importstaticjava.util.stream.Collectors.toList;
Mapping deeper
flatMap allows you to perform the map process on arrays of arrays. Each artist has an array of songs, so we can flat map (at the artist level) to emit a flat list of songs:
Scala has the concept of implicit parameters which allows the developer to implicitly apply a value that has been previously defined. According to the documentation
A method with implicit parameters can be applied to arguments just like a normal method. In this case the implicit label has no effect. However, if such a method misses arguments for its implicit parameters, such arguments will be automatically provided.
An example
We’ll create a Person class that expects a first and last name. There’s also a manager field to be supplied:
Immediately, you can see that the manager parameter has been decorated with the implicit keyword. What this says is:
First, any Person that can be accessed (at the point of construction) that has been declared implicit.
Second, any Person also declared implicit in companion modules.
For demonstration purposes, a showHierarchy function has been created to show management:
defshowHierarchy()={print(s"$firstName $lastName is ")if(manager==null){println("not managed by anybody")}else{valmanagerFirstName=manager.firstNamevalmanagerLastName=manager.lastNameprintln(s"managed by $managerFirstName $managerLastName")}}
When the Person has a manager, you’ll see their name; otherwise this function will show that they are “not managed by anybody”.
Using the class
With all of this definition, we now take a look at usage. Note that the manager parameter has a default value of null. So, any invocation where an implicit can not be supplied still doesn’t need to be specified as it’s been defaulted.
Sam Brown is not managed by anybody
Joe Smith is not managed by anybody
Makes sense. sam wasn’t declared as implicit and as such, wouldn’t be offered in the construction of joe. So, we modify the construction of sam and add the keyword:
implicitvalsam=Person("Sam","Brown")
This has an immediate impact on the output of the program:
Sam Brown is not managed by anybody
Joe Smith is managed by Sam Brown
As you can see, sam has now been implicitly offered to the construction of joe and as such, the manager parameter gets filled (in the construction of joe).