I'm trying the understand the following method reference code using Lambda expressions in Java:
interface MyFunc<T> {
boolean func(T v1, T v2);
}
class HighTemp {
private int hTemp;
HighTemp(int ht) {
hTemp = ht;
}
boolean sameTemp(HighTemp ht2) {
return hTemp == ht2.hTemp;
}
boolean lessThanTemp(HighTemp ht2) {
return hTemp < ht2.hTemp;
}
}
class InstanceMethWithObjectRefDemo {
static <T> int counter(T[] vals, MyFunc<T> f, T v) {
int count = 0;
for (int i = 0; i < vals.length; i++) {
if (f.func(vals[i], v)) {
count++;
}
}
return count;
}
public static void main(String args[]) {
int count;
HighTemp[] weekDayHighs = {new HighTemp(89), new HighTemp(82),
new HighTemp(90), new HighTemp(89),
new HighTemp(89), new HighTemp(91),
new HighTemp(84), new HighTemp(83)};
count = counter(weekDayHighs, HighTemp::sameTemp,
new HighTemp(89));
System.out.println(count + " days had a high of 89");
HighTemp[] weekDayHighs2 = {new HighTemp(32), new HighTemp(12),
new HighTemp(24), new HighTemp(19),
new HighTemp(18), new HighTemp(12),
new HighTemp(-1), new HighTemp(13)};
count = counter(weekDayHighs2, HighTemp::sameTemp,
new HighTemp(12));
System.out.println(count + " days had a high of 12");
count = counter(weekDayHighs, HighTemp::lessThanTemp,
new HighTemp(89));
System.out.println(count + " days had a high less than 89");
count = counter(weekDayHighs2, HighTemp::lessThanTemp,
new HighTemp(19));
System.out.println(count + " days had a high of less than 19");
}
}
My question is, why function sameTemp has just one parameter? The interface declare sthat it must have 2 parameters, so make no sense for me. Maybe the hTemp instance variable is enough for both? I took this from Java the complete reference book and there the author explains this:
Blockquote
In the program, notice that HighTemp has two instance methods:
sameTemp( )
andlessThanTemp( )
. The first returns true if two HighTemp objects contain the same temperature. The second returns true if the temperature of the invoking object is less than that of the passed object. Each method has a parameter of type HighTemp and each methoreturns a boolean result. Thus, each is compatible with the MyFunc functional interface because the invoking object type can be mapped to the first parameter offunc( )
and the argument mapped tofunc( )
’s second parameter.
Thanks!
What many people overlook when doing OO programming is ... how that is really implemented. Assume:
The point is: the idea of calling a method "on" an object is an abstraction. How would you implement that in assembler; so that a CPU can actually execute that code. You realize: "calling on" isnt possible there. On that level, you only call functions somewhere in memory. But how would a function know about its owning object?!
Leading to something that few people know - you can write the above code as:
To be on the safe side, I also wrote a little test in eclipse for that:
Runs fine in my eclipse, unit test passes, and prints "i: 5".
So, the whole secret is: when defining methods on an object, there is always an (normally invisible) first argument "this" given to that method!
Thus: although your methods look like taking only one parameter, the "missing" parameter is the object on which you are calling the method!
And in that sense:
boolean func(T v1, T v2)
asks for two parameters of type T. And both methods, likeboolean sameTemp(HighTemp ht2)
... can be written asboolean sameTemp(HighTemp this, HighTemp ht2)
; et voila: two parameters of type T.