I am currently solving the following programming exercise: Find the unique number The statement is:
There is an array with some numbers. All numbers are equal except for one. Try to find it!
Kata.findUniq(new double[]{ 1, 1, 1, 2, 1, 1 }); // => 2 Kata.findUniq(new double[]{ 0, 0, 0.55, 0, 0 }); // => 0.55
It’s guaranteed that array contains more than 3 numbers.
The tests contain some very huge arrays, so think about performance.
First my thought was to get all elements frequencies as a map, and then return the key which frequency value is just 1.
I wrote the following:
import java.util.stream.*;
public class Kata {
public static double findUniq(double arr[]) {
Map<Double, Long> frequencies = Arrays.stream(arr)
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
System.out.println("Map: "+map);
}
}
So it outputs:
./src/main/java/Kata.java:8: error: method collect in interface DoubleStream cannot be applied to given types;
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
^
required: Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
found: Collector<Object,CAP#1,Map<Object,Long>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
where R is a type-variable:
R extends Object declared in method <R>collect(Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
./src/main/java/Kata.java:10: error: cannot find symbol
System.out.println("Map: "+map);
^
symbol: variable map
location: class Kata
2 errors
I suppose the way to solve this issue is to understand:
required: Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
found: Collector<Object,CAP#1,Map<Object,Long>>
I do know it expects: Supplier<R>,ObjDoubleConsumer<R>,BiConsumer<R,R>
and I am writting: Collector<Object,CAP#1,Map<Object,Long>>
but what does it mean? How could we fix it? Why is it generated?
Then I tried a second approach: use a HashSet to get all distinct doubles, then remove the one which is not unique, and return the unique one, which is stored in the HashSet.
import java.util.*;
import java.util.stream.*;
public class Kata {
public static double findUniq(double arr[]) {
System.out.println("\nOriginal array: "+Arrays.toString(arr));
Set<Double> unique = new HashSet<Double>();
double repeated = Double.MIN_VALUE;
for(int i = 0; i < arr.length; i++){
if(repeated != arr[i] && !unique.add(arr[i])){
repeated = arr[i];
}
}
unique.remove(repeated);
System.out.println("Set: "+Arrays.toString(unique.toArray()));
return (double)unique.toArray()[0];
}
}
My question is, how could we achieve to return the unique element, using the first approach, counting frequencies with a map and then returning the key which value is 1‽.
I have also read:
Java Hashmap: How to get key from value? How to get unique items from an array?