Interested in an intensive two-day Java 8 training course?
Please visit our sponsor: Iteratr Learning.

Java 8 Articles
A couple of Articles explaining some of the key features of Java 8.
Java Duke
Lambda

The Benefits


Java 8 isn't your parent’s Java anymore. It is the largest update to Java in its history. It's a very exciting time. Some of the best ideas from functional programming are migrating their way into Java 8. This means easier to read, more flexible code that scales to multicore.

At the end of this course, you will be ready to use Java 8 on your day job and be familiar with the cutting edge programming approaches which allow you to write more flexible and concise code.

If you're interested in hearing more, here's a sneak peak video explaining how first class functions work:

Articles



Unit Testing Lambda Expressions & Streams


Usually, when writing a unit test you call a method in your test code that gets called in your application. Given some inputs and possibly test doubles, you call these methods to test a certain behavior happening and then specify the changes you expect to result from this behavior.

Lambda expressions pose a slightly different challenge when unit testing code. Because they don’t have a name, it’s impossible to directly call them in your test code. You could choose to copy the body of the lambda expression into your test and then test that copy, but this approach has the unfortunate side effect of not actually testing the behavior of your implementation. If you change the implementation code, your test will still pass even though the implementation is performing a different task.

There are two viable solutions to this problem. The first is to view the lambda expression as a block of code within its surrounding method. If you take this approach, you should be testing the behavior of the surrounding method, not the lambda expression itself.

Here’s an example method for converting a list of strings into their uppercase equivalents.

public static List<String> allToUpperCase(List<String> words) {
    return words.stream()
                .map(string -> string.toUpperCase())
                .collect(Collectors.toList());
}
                

The only thing that the lambda expression in this body of code does is directly call a core Java method. It’s really not worth the effort of testing this lambda expression as an independent unit of code at all, since the behavior is so simple.

If I were to unit test this code, I would focus on the behavior of the method. For example, here is a test that if there are multiple words in the stream, they are all converted to their uppercase equivalents.

@Test
public void multipleWordsToUppercase() {
    List<String> input = Arrays.asList("a", "b", "hello");
    List<String> result = allToUpperCase(input);
    assertEquals(asList("A", "B", "HELLO"), result);
}
                

Sometimes you want to use a lambda expression that exhibits complex functionality. Perhaps it has a number of corner cases or a role involving calculating a highly important function in your domain. You really want to test for behavior specific to that body of code, but it’s in a lambda expression and you’ve got no way of referencing it.

As an example problem, let’s look at a method that is slightly more complex than con‐ verting a list of strings to uppercase. Instead, we’ll be converting the first character of a string to uppercase and leaving the rest as is. If we were to write this using streams and lambda expressions, we might write something like the following.

public static List<String> uppercaseFirstChar(List<String> words) {
    return words.stream()
                .map(value -> {
                    char firstChar = value.charAt(0);
                    firstChar = toUpperCase(firstChar);
                    return firstChar + value.substring(1);
                })
                .collect(Collectors.toList());
}
                

Should we want to test this, we’d need to fire in a list and test the output for every single example we wanted to test. The test below provides an example of how cumbersome this approach becomes. Don’t worry—there is a solution!

@Test
public void twoLetterStringConvertedToUppercaseLambdas() {
    List<String> input = Arrays.asList("ab");
    List<String> result = uppercaseFirstChar(input);
    assertEquals(Arrays.asList("Ab"), result);
}
                

Don’t use a lambda expression! I know that might appear to be strange advice in an article about lambda expressions, but square pegs don’t fit into round holes very well. Having accepted this, we’re bound to ask how we can still unit test our code and have the benefit of lambda-enabled libraries.

Do use method references. Any method that would have been written as a lambda expression can also be written as a normal method and then directly referenced elsewhere in code using method references. In the code below I’ve refactored out the lambda expression into its own method. This is then used by the main method, which deals with converting the list of strings.

public static List<String> uppercaseFirstChar(List<String> words) {
    return words.stream()
                .map(Testing::firstToUppercase)
                .collect(Collectors.toList());
}

public static String firstToUppercase(String value) {
    char firstChar = value.charAt(0);
    firstChar = toUpperCase(firstChar);
    return firstChar + value.substring(1);
}
                

Having extracted the method that actually performs string processing, we can cover all the corner cases by testing that method on its own. The same test case in its new, simplified form is shown here:

@Test
public void twoLetterStringConvertedToUppercase() {
    String input = "ab";
    String result = uppercaseFirstChar(input);
    assertEquals("Ab", result);
}
                

The key takeaway here is that if you want to unit test a lambda expression of serious complexity, extract it to a regular method first. You can then use method references to treat it like a first-class function.



If you want to learn more then please visit our sponsor: Iteratr Learning.



First Class Functions


Java 8 adds functions as a new form of value. What does this mean? Let’s look at a simple example.

Suppose you want to filter all the hidden files in a directory. You need to start writing a method that given a File will tell you whether it is hidden or not. Thankfully there’s such a method inside the File class called isHidden. It can be viewed as a function that takes a File and returns a boolean.

However, to use it you need to wrap it into a FileFilter object that you then pass to the File.listFiles method as follows:

  File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
      public boolean accept(File file) {
          return file.isHidden();
      }
  });
                

Ouch, that’s pretty obscure! We already have a function isHidden that we could use, why do we have to wrap it up in a verbose FileFilter object?

In Java 8 you can rewrite that code as follows:

  File[] hiddenFiles = new File(".").listFiles(File::isHidden);
                

Wow! Isn’t that cool? We already have the function isHidden available so we just “pass” it to the listFiles method. Our code now reads closer to the problem statement.

The use of File::isHidden is a rather special case of a new feature called method references in Java 8. Given that methods contain code (the executable body of a method), then using methods as values is like passing code around.

Contact Us


If you would like to know more about Java 8 then you can either email us at java8training@googlegroups.com or complete this form.