JavaOne- Lambdas Chops: Recipes for simpler more expressive code

“Lambdas Chops: Recipes for simpler more expressive code”

Speaker: Ian Robertson
slidehare.net/nainostrebor

For more blog posts from JavaOne, see the table of contents


Disclaimer: These are now the most performant way of doing things. If you have I/O or database code, it won’t be a significant difference.

Did one slide review of lambdas as “test” for whether kow enough to follow rest of session. [good idea]

Null safe navigation

  • In Groovy, a?.getX()?.getY()
  • Call method if object is non-null, otherwise just return null
  • Best route is to refactor to return Optional from the getters
  • If can’t refactor: Optional.ofNullable(employee).ap(Employee::getAddress).map(Address::getCity).orElse(null)
  • By chaining Optional can decide what to do

First non null

  • commons-lang has ObjectUtils.firstNonNull
  • Works will if values are cheap to provide
  • If expensive/time consuming, waiting for wasted work
  • firstNonNull(customer.getCart():getRecommendations, this::getBestSellers)
  • and firstNonNull now would have- Stream.of(values).map(Supplier:get).filter(Objects:nonNull).findFIrst().orElse(null)

Multi-method interfaces

  • Helper methods can create instances from one or more lambdas
  • Showed with SimpleFieVisitor. [i don’t see a lambda or method reference here. He mentioned a lambda, but there are no abstract methods now]

Exceptions

  • forEach(File::createNewFile) – doesn’t compile because throws IOException
  • Tried to solve in language and couldn’t.
  • Can catch exception in lambda and convert to runtime exception, but now code is long
  • jOOL library create companion interface that allows checked exceptions and converts to runtime exception
  • now write forEach(Unchecked.consumer(File::createNewFile))

Design Pattern

  • Dispose pattern – close in proper place [no null check in example]
  • Try-with-resources added in Java 7
  • Can forget; poor API that lets you forget
  • Must implement AutoCloseable
  • Can have close logic or lock/unlock in one place and pass lambda [still have to remember to call that]
  • Vavr (Java upside down) library has good library for lazy evaluation (double checked locking pattern) – pass lambda wih work

Type safety

  • Many APIs rely on String representation of method names
  • ex: commmons-beanutils takes method name for comparators. “stringly typed”
  • JDK added API that takes method reference Comparator.comparing(Person::getLastName).thenComparing(Person:getFirstName)
  • Now type safe

JUnit 5 Parameterized Tests

  • @MethodSource has “stringly typed” problem. Also, no way to know passing right # parameters and types
  • Alternatively can use @TestFactory and DynamicTests to have compile time type safety
  • Harder to read with tuples. Can improve further with helper method per combo and have tests use it.
  • [the lack of type safety doesn’t seem like a big deal here since run tests regularly so would know if mismatch. And parameterized tests are much easier to read ]
  • Wrote LambdataRunner to do this in JUnit 4

Best Practices

  • Have more single method interfaces. Provide static helper methods to create
  • Use existing interfaces where can instead of writing own. Easier because already know what it is
  • Avoid overloading method names to accept different lambas of same “shape”. Compiler says lamda ambigious and require lients to cast

My take: I really liked the discussion of pros and cons. And the emoticons were fun – happy, sad, angry, meh. I don’t like the JUnit example, but the rest sound like things I’d do/try.

The 8 Nights of Java – Night 8

It’s been a fun 8 Nights of Java, but alas, tonight is the final post. Java 8 added one of the most radical, most drastic changes to date, even bigger than Java 5 or Java 7: lambdas and streams! The writers of Java updated nearly every Java API to include lambda expression and stream-based methods. More than the API changes, though, they present a new paradigm for thinking about programming. The closest thing to a lambda expression prior to Java 8 was an anonymous inner class, and it a lot of ways they are similar, but the syntax and usability of lambda expressions is unmatched.

We hope everyone had a wonderful holiday season and we hope that you have a Happy New Year! Don’t forget, we have a brand new OCA/OCP 8 book coming out in March 2017. Order yours now on Amazon.com!

Jump to: [Night 1 | Night 2 | Night 3 | Night 4 | Night 5 | Night 6 | Night 7 | Night 8]

Java 8 Notable Features

Oracle released Java 8 on March 18, 2014. If you’ve read the previous nights in this series, you might be wondering what the codename of Java 8 was. Oracle decided not to use one. Luckily, our friends at the Javaranch had some ideas. We like “Cuddles” ourselves.

Key new functionality included:

  • Functional interfaces
  • Lambda expressions
  • Streams
  • New date/time library
  • Project Nashorn

From Jeanne:

Streams and lambdas are one of my favorite additions to the language of all time. They make it easy to write expressive code. I haven’t needed the benefits of multi-core parallelization much yet, but it is nice to know it is there. Even without that, I find my stream based code to be shorter and easy to write/read. It took me a little while to get fluent but I went through that with Groovy before Java so I was ready when it came to Java. I was the first person on my team to write a Java 8 program for work. I commented almost every line so it could be used as a teaching example. That was fun!

The date/time library is also cool. I like that it is expressive and has so much more functionality than the Calendar API. Third time for a date API really was the charm. I just wish they retrofitted it to work directly with more libraries like JDBC. Then there’s Nashorn. A JavaScript console was a good idea, but I don’t think this one is it.

From Scott:

Two things I love about lambda expressions and streams in Java 8. First, they found a way to build functional programming into Java, by using functional interfaces. While the signature for some of the built-in functional interfaces can be… hard to read… using or creating lambda expressions rarely requires understanding the signature. That’s what is so cool about what they did. They added this conversion of lambda expressions to functional interfaces to anonymous inner classes, but from a developers perspective, all we have to know how to do is write a simple one-line lambda expression! Very cool they way they added this on without breaking the language.

The second thing I love is they included parallel streams in the very first version! It’s so awesome to be able to have built-in easy support for concurrency without having to create/manage/shutdown an executor service. One feature request for Java 9? I *really* would prefer a way to set the number of threads in a parallel stream, such as stream.parallel(10) for 10 threads. Currently, it’s controlled by the JVM based on the number of threads on the computer and unable to be changed by a developer. Here’s hoping they add it to a future version of Java!

There’s still so much more to love about Java 8! As I was saying on Night 7, Java 7 improved the Concurrency API while introducing NIO.2, but both became even more powerful in Java 8. Creating Runnable and Callable instances using anonymous inner classes was already common prior to Java 8, but it was at times verbose. You had to create a class definition, override a method, set up a generic return type for Callable, etc. While not difficult to do, it did take up multiple lines of bloated code, copied over and over again for each task. Lambda expressions fit perfectly in the Concurrency API, better than any other API (with the possible exception of Collections), in that it allowed developers to submit tasks to a thread executor in a single, simple line of code using a lambda expression. In other words, they made Concurrency, one of the arguably most difficult spaces for developers to work in, much easier to understand and implement.

java 8 – writing a timer

A member at CodeRanch asked a question that prompted me to write a qucik program to determine which of two String operations were faster. This is the first time my instinct was to use Java 8 functionality to do it.

The interesting features:

  1. Uses Instant and Duration instead of System.currentTimeMillis().
  2. Uses functional programming to pass the expression to run to the timer rather than duplicating the timer logic or using a subclass
  3. Uses underscores to make # iterations more readable. (Ok, this is Java 7 not Java 8)
public class PlayTest {

	public static void main(String[] args) throws Exception {

		timer("string concatenation", () -> "/root/" + getFolderName()
				+ "/subfolder");
		timer("string format",
				() -> String.format("/root/%s/subfolder", getFolderName()));

	}

	private static void timer(String message, Supplier<String> candidate) {
		Instant start = Instant.now();
		int times = 1_000_000;

		for (int i = 0; i < times; i++) {
			candidate.get();
		}
		Instant end = Instant.now();
		System.out.println(message + " : " + Duration.between(start, end));
	}

	private static String getFolderName() {
		return "foo";
	}

}

The old way (for comparison)

public static void oldWay() {
		long before = System.currentTimeMillis();
		int times = 1_000_000;

		for (int i = 0; i < times; i++) {
			String s = "/root/" + getFolderName() + "/subfolder";
		}
		long after = System.currentTimeMillis();
		System.out.println("String concatenation: " + (after - before));
	}

The output

The output is also clearer.

string concatenation : PT0.5533S

Vs

string concatenation : 553

I actually get units of time without doing anything special now. And in case you are wondering, the conclusion is that string concatenation is faster. I expected that. It was way faster than I expected though. Twenty times faster.