{"id":3255,"date":"2023-03-27T17:50:48","date_gmt":"2023-03-27T16:50:48","guid":{"rendered":"https:\/\/www.xenonique.co.uk\/blog\/?p=3255"},"modified":"2023-03-27T17:50:49","modified_gmt":"2023-03-27T16:50:49","slug":"java-interview-answer-q2-duplicate-integers-and-sort","status":"publish","type":"post","link":"https:\/\/www.xenonique.co.uk\/blog\/2023\/03\/27\/java-interview-answer-q2-duplicate-integers-and-sort\/","title":{"rendered":"Java Interview Answer Q2 &#8211; Duplicate Integers and Sort"},"content":{"rendered":"\n<p>Last week, I presented a <a href=\"https:\/\/www.xenonique.co.uk\/blog\/2023\/03\/20\/java-interview-question-2-duplicate-integers-and-sort\/\">Java Interview Question 2: How to Find Duplicate Integers and Sort<\/a>? We had a test harness to find all duplicate integers in a list collection. We wanted a sorted set of integers as a String text output. <\/p>\n\n\n\n<p>A modern Java solution is the following:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class DuplicateIntegersFintechJobSoftwareTest {\n \n     \/\/...\n\n    \n     public String search_duplicates_sort_them(List&lt;Integer&gt; numberList) {\n\n        var histogram = new HashMap&lt;Integer, Integer&gt;();\n        numberList.stream().forEach(digit -&gt; {\n                    if (histogram.containsKey(digit)) {\n                        histogram.put(digit, histogram.get(digit) + 1);\n                    } else {\n                        histogram.put(digit, 1);\n                    }\n                }\n        );\n\n        System.out.printf(&quot;histogram=%s\\n&quot;, histogram);\n\n        var duplicates = histogram.entrySet().stream().filter(\n                tuple -&gt; {\n                    return tuple.getValue() &gt; 1;\n                }).map(tuple -&gt; tuple.getKey()).sorted().toList();\n        System.out.printf(&quot;duplicates=%s\\n&quot;, duplicates);\n\n        var buf = new StringBuilder();\n        duplicates.stream().findFirst().ifPresent( x -&gt; buf.append(x));\n        duplicates.stream().skip(1).forEach( x -&gt; buf.append(&quot;, &quot;+x));\n\n        System.out.printf(&quot;&gt;&gt;&gt;&gt; buf='%s'\\n\\n&quot;, buf.toString());\n        return buf.toString();\n    }\n\n    \/\/...\n}\n<\/pre><\/div>\n\n\n<p>I coded against Java 19, however this code should work against Java 16. I am fairly sure the <strong>List.of(&#8230;) <\/strong>was introduced in 16. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/vkWlEQdeuVY\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Java Lambda functions can be complicated to interpret. So I say to code review submitter to subjectively ensure your code is readable weeks, if not months later. Break it down and use local variables to store stream results. <\/p>\n\n\n\n<p>The first part of the function, builds a histogram of the input numbers. Remember in Java (Kotlin and Scala too), map collections are collection of Key-Value pairs. In Java, we call this pair <code>EntrySet<\/code>, in Kotlin and Scala, it is a Tuple of 2 elements. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nvar histogram = new HashMap&lt;Integer, Integer&gt;();\n        numberList.stream().forEach(digit -&gt; {\n                    if (histogram.containsKey(digit)) {\n                        histogram.put(digit, histogram.get(digit) + 1);\n                    } else {\n                        histogram.put(digit, 1);\n                    }\n                }\n        );\n<\/pre><\/div>\n\n\n<p>In the above, for the input <code>numberList<\/code> we call the stream <code>forEach()<\/code> function in order build the histogram that represents the occurrances of a number. We get a map collection <code>histogram={1=1, 2=1, 3=1, 4=2, 5=1, 6=1, 7=2, 8=1}<\/code><\/p>\n\n\n\n<p>In the second step, we need to filter out the duplicates. We enumerate across the stream of entry sets, but this time in the histogram. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nvar duplicates = histogram.entrySet().stream().filter(\n                tuple -&gt; {\n                    return tuple.getValue() &gt; 1;\n                }).map(tuple -&gt; tuple.getKey()).sorted().toList();\n<\/pre><\/div>\n\n\n<p>In above, we filter for histogram values greater than one, or numbers that have more one occurance. The data type is <code>EntrySet[Integer,Integer]<\/code>. However, notice the second operation. After the <code>filter()<\/code> operation, we invoke a <code>map()<\/code> operation that converts the key (our number) into a single element <code>Integer<\/code>. Finally, a third operation, we call sorted() that sorts our final stream into ascending order then turns it into a list collection! Phew! <code>List[Integer]<\/code><\/p>\n\n\n\n<p>The third step does requires Java 16.  For Scala and Kotlin folk this is very easy, because you know that lists can have head (<code>x<\/code>) and tail (<code>xs<\/code>), and it will be familiar. This is functional programming, properly. <\/p>\n\n\n\n<p>We want to concatenate and join together elements in our final list collection. Here is the traditional way of writing this code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n       var buf = new StringBuilder();\n       for (int i = 0; i &lt; duplicates.size(); i++) {\n            if (i != 0) {\n                buf.append(&quot;, &quot;);\n            }\n            buf.append(duplicates.get(i));\n       }\n<\/pre><\/div>\n\n\n<p>Here is the Modern Java way of solving this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n        var buf = new StringBuilder();\n        duplicates.stream().findFirst().ifPresent( x -&gt; buf.append(x));\n        duplicates.stream().skip(1).forEach( x -&gt; buf.append(&quot;, &quot;+x));\n        return buf.toString()\n<\/pre><\/div>\n\n\n<p>The  funky nearest equivalent to <code>head()<\/code> is Java, is invoke findFirst(), deal with the Optional&lt;Integer&gt;. We just append the first duplicate.  The funky nearest equivalent to <code>tail()<\/code> in Java, is invoke <code>skip(X)<\/code>, where <code>X<\/code> specifies the number of elements to skip over in the stream. We then enumerate across the rest of the stream. There is one more bit that I would clean up. <code>return buf.toString()<\/code>.  I would remove the <code>toString()<\/code> call, because that is an implied Java language conversion. You see, olde school rapping dies hard!<\/p>\n\n\n\n<p>That&#8217;s it. <\/p>\n\n\n\n<p>Hope you enjoyed it. See you at the next lecture!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Peter Pilgrim<\/p>\n\n\n\n<p>March 2023<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>I am open to work (Permanent or Contract)<\/p>\n\n\n\n<p>Please read my linkedin profile for accurate information <a href=\"https:\/\/www.linkedin.com\/in\/peterpilgrim2000\/\">www.linkedin.com\/in\/peterpilgrim2000<\/a><br>and also my Github profile <a href=\"https:\/\/peterpilgrim.github.io\/digital-cv\/\">https:\/\/peterpilgrim.github.io\/digital-cv\/<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last week, I presented a Java Interview Question 2: How to Find Duplicate Integers and Sort? We had a test harness to find all duplicate integers in a list collection. We wanted a sorted set of integers as a String text output. A modern Java solution is the following: I coded against Java 19, however [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[202,78,117,4,31,214],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/3255"}],"collection":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=3255"}],"version-history":[{"count":3,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/3255\/revisions"}],"predecessor-version":[{"id":3258,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/3255\/revisions\/3258"}],"wp:attachment":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=3255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=3255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=3255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}