{"id":327,"date":"2013-12-08T15:19:35","date_gmt":"2013-12-08T14:19:35","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=327"},"modified":"2013-12-08T21:20:56","modified_gmt":"2013-12-08T20:20:56","slug":"null-coalescing-in-java-8","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/","title":{"rendered":"Null Coalescing in Java 8"},"content":{"rendered":"<p class=\"lead\"><a href=\"http:\/\/en.wikipedia.org\/wiki\/Null_%28SQL%29#COALESCE\">SQL<\/a> gives us a &#8220;coalesce&#8221; function, which returns the first non-null argument. <\/p>\n<p>This seems to be a common operation in Java too, since Java unfortunately burdens us with the concept of nulls. We have been able to do something similar with Java for some time using a varargs method like this:<\/p>\n<pre lang=\"java\">\r\n    public static <T> T coalesce(T... ts) {\r\n        for (T t : ts)\r\n            if (t != null)\r\n                return t;\r\n        \r\n        return null;\r\n    }\r\n\r\n    String result = coalesce(somethingPossiblyNull(), somethingElse(), \"defaultValue\");\r\n<\/pre>\n<p>(There is a similar method on <a href=\"http:\/\/docs.guava-libraries.googlecode.com\/git\/javadoc\/com\/google\/common\/base\/Objects.html#firstNonNull%28T,%20T%29\">Guava&#8217;s Objects<\/a> class);<\/p>\n<p>It looks nice and avoids the need for ugly ifs in some places. However, unfortunately it means that somethingElse() would have to be evaluated even if somethingPossiblyNull() returned a non-null value. This is not what we want if these are expensive, so we had to fall back to something less clean.<\/p>\n<p>In Java 8 thanks to lambdas &amp; method references we can do this lazily.<\/p>\n<pre lang=\"java\">\r\n    public static <T> T coalesce(Supplier<T>... ts) {\r\n        return asList(ts)\r\n            .stream()\r\n            .map(t -> t.get())\r\n            .filter(t -> t != null)\r\n            .findFirst()\r\n            .orElse(null);\r\n    }\r\n\r\n    @Test\r\n    public void should_return_first_non_null_value() {\r\n        Person nullName = new Person(null);\r\n        Person bob = new Person(\"bob\");\r\n        Person barbara = new Person(\"barbara\");\r\n\r\n        assertEquals(\"bob\", coalesce(nullName::name, bob::name, barbara::name));\r\n    }\r\n<\/pre>\n<p>Here we pass in suppliers for the values rather than the values themselves. First we invoke the supplier to get the value, then filter it out if it is null (as we are looking for the first non-null value), and then return the first matching &#8211; meaning that we do not look farther through the list of passed values than we need to.<\/p>\n<p>We can demonstrate that we do not invoke unnecessary methods <\/p>\n<pre lang=\"java\">\r\n    @Test\r\n    public void should_be_lazy() {\r\n        Person bob = new Person(\"bob\");\r\n        Person angryPerson = new Person(\"angry\") {\r\n            @Override public String name() {\r\n                fail(\"Should not have asked for the angry person's name\");\r\n                return \"angry\";\r\n            }\r\n        };\r\n\r\n        assertEquals(\"bob\", coalesce(bob::name, angryPerson::name));\r\n    }\r\n<\/pre>\n<p>Here we never invoke the name method on angryPerson because bob had a non-null name.<\/p>\n<p>If we want to do something more complicated than calling a Supplier-like method we can always use lambdas<\/p>\n<pre lang=\"java\">\r\n    @Test\r\n    public void should_be_able_to_use_lambdas() {\r\n        assertEquals(\"bob\", coalesce(() -> new Person(\"bob\").name(), () -> new Person(\"barbara\").name()));\r\n    }\r\n<\/pre>\n<p>Or, if people ever stop returning nulls all over the place then you can of course do the same with <a href=\"http:\/\/download.java.net\/jdk8\/docs\/api\/java\/util\/Optional.html\">Optional<\/a>s <\/p>\n<p>The AnotherSupplier interface is just to work around Type Erasure terribleness.<\/p>\n<pre lang=\"java\">\r\n    @Test\r\n    public void should_be_able_to_use_optionals() {\r\n        assertEquals(\"bob\",\r\n            coalesce(\r\n                () -> Optional.<String>empty(),\r\n                () -> Optional.of(new Person(\"bob\").name()),\r\n                () -> Optional.of(new Person(\"barbara\").name())\r\n            ).get()\r\n        );\r\n    }\r\n\r\n    interface AnotherSupplier<T> extends Supplier<T> {}\r\n\r\n    public static <T> Optional<T> coalesce(AnotherSupplier<Optional<T>>... ts) {\r\n        return asList(ts)\r\n                .stream()\r\n                .map(t -> t.get())\r\n                .filter(t -> t.isPresent())\r\n                .findFirst()\r\n                .orElse(Optional.<T>empty());\r\n    }\r\n\r\n<\/pre>\n<p>By the way &#8211; C# <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms173224.aspx\">provides an operator for doing this<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/benjiman\/expressions\/blob\/master\/src\/main\/java\/uk\/co\/benjiweber\/expressions\/Coalesce.java\">Code on github<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>SQL gives us a &#8220;coalesce&#8221; function, which returns the first non-null argument. This seems to be a common operation in Java too, since Java unfortunately burdens us with the concept of nulls. We have been able to do something similar with Java for some time using a varargs method like this: public static T coalesce(T&#8230;&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/\" class=\"more-link\" title=\"Read Null Coalescing in Java 8\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Null Coalescing in Java 8 - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"SQL gives us a &#8220;coalesce&#8221; function, which returns the first non-null argument. This seems to be a common operation in Java too, since Java unfortunately burdens us with the concept of nulls. We have been able to do something similar with Java for some time using a varargs method like this: public static T coalesce(T...... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-12-08T14:19:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-12-08T20:20:56+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/\",\"name\":\"Benji&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/benjiweber.co.uk\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/\",\"name\":\"Null Coalescing in Java 8 - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"datePublished\":\"2013-12-08T14:19:35+00:00\",\"dateModified\":\"2013-12-08T20:20:56+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2013\/12\/08\/null-coalescing-in-java-8\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\",\"name\":\"benji\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05fb47b31a0b329e1b790074a9b624ef?s=96&d=mm&r=g\",\"caption\":\"benji\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/327"}],"collection":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=327"}],"version-history":[{"count":15,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/327\/revisions"}],"predecessor-version":[{"id":342,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/327\/revisions\/342"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}