2023-03-27

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 this code should work against Java 16. I am fairly sure the List.of(…) was introduced in 16.

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.

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 EntrySet, in Kotlin and Scala, it is a Tuple of 2 elements.

In the above, for the input numberList we call the stream forEach() function in order build the histogram that represents the occurrances of a number. We get a map collection histogram={1=1, 2=1, 3=1, 4=2, 5=1, 6=1, 7=2, 8=1}

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.

In above, we filter for histogram values greater than one, or numbers that have more one occurance. The data type is EntrySet[Integer,Integer]. However, notice the second operation. After the filter() operation, we invoke a map() operation that converts the key (our number) into a single element Integer. Finally, a third operation, we call sorted() that sorts our final stream into ascending order then turns it into a list collection! Phew! List[Integer]

The third step does requires Java 16. For Scala and Kotlin folk this is very easy, because you know that lists can have head (x) and tail (xs), and it will be familiar. This is functional programming, properly.

We want to concatenate and join together elements in our final list collection. Here is the traditional way of writing this code:

Here is the Modern Java way of solving this:

The funky nearest equivalent to head() is Java, is invoke findFirst(), deal with the Optional<Integer>. We just append the first duplicate. The funky nearest equivalent to tail() in Java, is invoke skip(X), where X 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. return buf.toString(). I would remove the toString() call, because that is an implied Java language conversion. You see, olde school rapping dies hard!

That’s it.

Hope you enjoyed it. See you at the next lecture!

Peter Pilgrim

March 2023

I am open to work (Permanent or Contract)

Please read my linkedin profile for accurate information www.linkedin.com/in/peterpilgrim2000
and also my Github profile https://peterpilgrim.github.io/digital-cv/

Show more