Java Lambda expression parameters [duplicate]

2020-06-29 03:03发布

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( ) and lessThanTemp( ). 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 of func( ) and the argument mapped to func( )’s second parameter.

Thanks!

标签: lambda java-8
1条回答
一纸荒年 Trace。
2楼-- · 2020-06-29 03:11

What many people overlook when doing OO programming is ... how that is really implemented. Assume:

class C {
  public int foo(int parm) { return parm; }

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:

class C {
  public int foo(C this, int i) {
        System.out.println("i: " + i);
        return i;
   }
}

To be on the safe side, I also wrote a little test in eclipse for that:

@Test
public void testIt() {
    assertThat(new C().foo(5), is(5));
}

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, like boolean sameTemp(HighTemp ht2) ... can be written as boolean sameTemp(HighTemp this, HighTemp ht2); et voila: two parameters of type T.

查看更多
登录 后发表回答