Notice:

This page has been converted from a dynamic Wordpress article to a static HTML document. As a result, some content may missing or not rendered correctly.

Java 8's Lambda Expressions ~ Tue, 13 Jan 2015 19:36:15 +0000

Java 8 has introduced serveral good things. Perhaps my favorite of the list are the lambda expressions. They go a long way toward catching Java up to JavaScript (oh the irony), but I ran into an issue when attempting to use them; an issue that frustrated me enough to write this. I'd like to note up-front that this irritation came about because I was using Java's lambdas without first fully understanding them. Regardless...

The first opportunity I had to really use a Java lambda came about when writing a couple toString() methods. Let's look at the first one, the one that had me thanking the Java 8 gods:

public class Foobar {
  private final Map values = new HashMap<>();

  // Implementation
  // ...
  // ...
  // ...

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();

    this.values.forEach(
      (k, v) -> sb.append(
        String.format("[%s : %s]\n", k, v)
      )
    );

    return sb.toString();
  }
}

It may not seem like much, but the lambda got rid of a boring for loop:

for (String k : this.values.keySet()) {
  sb.append(
    String.format("[%s : %s]\n", k, this.values.get(k))
  );
}

So, yay, it made generating a string from a HashMap a little easier and quicker to type. Now let's look at another toString() method. This one will render the fields of the class individually instead of a single map of values:

public class Foobar {
  private final String foo = "bar";
  private final String bar = "baz";
  // more fields
  // ...
  // ...

  // Implementation
  // ...
  // ...
  // ...

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();

    Formatter format = (a, b) -> {
      sb.append(String.format("%15-s: %s", a, b));
      return null;
    };

    format("foo", this.foo);
    format("bar", this.bar);

    return sb.toString();
  }

  private interface Formatter {
    Function format(String a, String b);
  }
}

I find that to be rather silly. It'd be shorter to simply add a new private method to the class that will accept the two parameters and return a formatted string. But that doesn't make any sense because the format function is only relevant to the toString() method.

Unlike other languages where lambdas are pure first-class functions[ref], the lambdas in Java 8 are a bit clunky. They're still great, but I find this limitation to be very annoying.

In summary, Java 8 has lambda expressions (yay!) but they could be better (boo!).

Code,  Java,  Opinion,  Technology