{"id":701,"date":"2015-02-20T21:49:56","date_gmt":"2015-02-20T20:49:56","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=701"},"modified":"2015-02-20T23:33:58","modified_gmt":"2015-02-20T22:33:58","slug":"work-around-java-same-erasure-errors-with-lambdas","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/","title":{"rendered":"Work around Java &#8220;same erasure&#8221; errors with Lambdas"},"content":{"rendered":"<p class=\"lead\">A common frustration with Java is the inability to overload methods when the method signatures differ only by type parameters. <\/p>\n<p>Here&#8217;s an example, we&#8217;d like to overload a method to take either a List of Strings or a List of Integers. This will not compile, because both methods have the same erasure. <\/p>\n<pre lang=\"java\">\r\nclass ErasureExample {\r\n\r\n    public void doSomething(List<String> strings) {\r\n        System.out.println(\"Doing something with a List of Strings \" );\r\n    }\r\n\r\n    public void doSomething(List<Integer> ints) { \r\n        System.out.println(\"Doing something with a List of Integers \" );\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>If you delete everything in the angle brackets the two methods will be identical, which is <a href=\"http:\/\/docs.oracle.com\/javase\/specs\/jls\/se5.0\/html\/classes.html#38649\">prohibited by the spec<\/a><\/p>\n<pre lang=\"java\">\r\npublic void doSomething(List<> strings) \r\npublic void doSomething(List<> strings)\r\n<\/pre>\n<p>As with most Java things &#8211; if it&#8217;s not working, you&#8217;re probably not using enough lambdas. We can make it work with just one extra line of code per method.<\/p>\n<pre lang=\"java\">\r\nclass ErasureExample {\r\n\r\n    public interface ListStringRef extends Supplier<List<String>> {}\r\n    public void doSomething(ListStringRef strings) {\r\n        System.out.println(\"Doing something with a List of Strings \" );\r\n    }\r\n\r\n    public interface ListIntegerRef extends Supplier<List<Integer>> {}\r\n    public void doSomething(ListIntegerRef ints) {\r\n        System.out.println(\"Doing something with a List of Integers \" );\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>Now we call call the above as simply as the following, which will print &#8220;Doing something with a List of Strings&#8221; followed by &#8220;Doing something with a List of Integers&#8221;<\/p>\n<pre lang=\"java\">\r\npublic class Example {\r\n    \r\n    public static void main(String... args) {\r\n        ErasureExample ee = new ErasureExample();\r\n        ee.doSomething(() -> asList(\"aa\",\"b\"));\r\n        ee.doSomething(() -> asList(1,2));\r\n    }\r\n}\r\n<\/pre>\n<p>Using the wrapped lists inside the method is straightforward. Here we print out the length of each string and print out each integer, doubled. It will cause the above main method to print &#8220;2124&#8221;. <\/p>\n<pre lang=\"java\">\r\nclass ErasureExample {\r\n\r\n    public interface ListStringRef extends Supplier<List<String>> {}\r\n    public void doSomething(ListStringRef strings) {\r\n        strings.get().forEach(str -> System.out.print(str.length()));\r\n    }\r\n\r\n    public interface ListIntegerRef extends Supplier<List<Integer>> {}\r\n    public void doSomething(ListIntegerRef ints) {\r\n        ints.get().forEach(i -> System.out.print(i * 2));\r\n    }\r\n\r\n}\r\n<\/pre>\n<p>This works because the methods now have different erasure, in fact the method signatures have no generics in at all. The only additional requirement is prefixing each argument with &#8220;() ->&#8221; at the callsite, creating a lambda that is equivalent to a <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/util\/function\/Supplier.html\">Supplier<\/a> of whatever type your argument is.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A common frustration with Java is the inability to overload methods when the method signatures differ only by type parameters. Here&#8217;s an example, we&#8217;d like to overload a method to take either a List of Strings or a List of Integers. This will not compile, because both methods have the same erasure. class ErasureExample {&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/\" class=\"more-link\" title=\"Read Work around Java &#8220;same erasure&#8221; errors with Lambdas\">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\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Work around Java &quot;same erasure&quot; errors with Lambdas - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"A common frustration with Java is the inability to overload methods when the method signatures differ only by type parameters. Here&#8217;s an example, we&#8217;d like to overload a method to take either a List of Strings or a List of Integers. This will not compile, because both methods have the same erasure. class ErasureExample {... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-02-20T20:49:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-02-20T22:33:58+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\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/\",\"name\":\"Work around Java \\\"same erasure\\\" errors with Lambdas - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"datePublished\":\"2015-02-20T20:49:56+00:00\",\"dateModified\":\"2015-02-20T22:33:58+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2015\/02\/20\/work-around-java-same-erasure-errors-with-lambdas\/\"]}]},{\"@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\/701"}],"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=701"}],"version-history":[{"count":7,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/701\/revisions"}],"predecessor-version":[{"id":708,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/701\/revisions\/708"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}