请使用类名解释Java 8方法参考实例方法
public interface MyFunc { boolean func(T v1, T v2); }
public class HighTemp { private int hTemp; HighTemp(){ } public HighTemp(int ht) { this.hTemp = ht; } boolean sameTemp(HighTemp ht2){ return hTemp == ht2.hTemp; } boolean lessThanTemp(HighTemp ht2){ return hTemp < ht2.hTemp; } }
class InstMethWithObjRef { static int counter(T[] vals, MyFunc 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; //Create an array of HighTemp objects. 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::lessThanTemp,new HighTemp(89)); System.out.println(count); } }
请解释一下
-
boolean sameTemp()
与Functional接口中的func()
兼容。 -
sameTemp()
方法在Functional Interface中的func()
上实现。 -
count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89));
工作中
请分别解释所有要点。
HighTemp::lessThanTemp
等效 lambda表达式是
(highTemp1, highTemp2) -> { return highTemp1.lessThanTemp(highTemp2); }
这是Java8
一个特性,名为对特定类型的任意对象的实例方法的引用
考虑以下示例,
interface FIface { int testMethod(T a, T b); } class Test2 { private String str; Test2(String str) { this.str = str; } int ok(Test2 test2) { System.out.println("Currnet String : "+ this.str);//Refer to t1 System.out.println("Test String : "+test2.str);//Refer to t2 return 0; } } public class Test { public static int checkCall(T t1, T t2, FIface fiFace) { //Here Test2 :: ok is equivalent to t1.ok(t2) return fiFace.testMethod(t1, t2); } public static void main(String[] args) { checkCall(new Test2("a"), new Test2("b"), Test2 :: ok); } }
OUTPUT
Currnet String : a Test String : b
注意这里Test2 :: ok
对于调用有效,即使ok
方法不是静态的。
当您为函数接口调用方法checkCall
,您仍然有两个参数,即t1
和t2
并且对于该有效的lambda表达式可以具有参数(Test t1, Test t2)
因此您的方法Test2 :: ok
在此处对调用有效。 在内部它以这种方式工作t1.ok(t2)
。
那么, fiFace.testMethod(t1, t2);
将调用方法为t1.ok(t2)
对于初学者我不是专业程序员。 我也很难理解所谓的“ 特定类型的任意对象的实例方法的参考 ”我认为这可能对从谷歌搜索来到这里的人有所帮助。
我在lambda表达式的帮助下理解了一点。
在你的代码中,作为Lambda表达式的HighTemp::lessThanTemp
看起来像(x,y)->{x.lessThanTemp(y);}
用这个lambda表达式替换方法引用会产生相同的结果。 上面的Lambda表达式或方法引用都告诉接口方法该做什么。
当您使用方法引用时,它告诉接口方法使用给定类中的引用方法来执行其function。 因此,如果您将HighTemp::lessThanTemp
转换为英语单词,它听起来就像“ 实现类HighTemp
的lessThanTemp
方法作为接口函数的实现 ”。 正如您可能已经注意到的那样,返回类型和参数类型应该是兼容的。 否则您无法实现接口。
我会提供另一个简单的示例代码。 更多示例有助于理解这一概念。
interface myint{ int returnit(Test t ,int y); } class Test{ int x=0; public Test(int x){ this.x=x; } public int addNumbers(int y){ return x+y; } public int subtractNumbers(int y){ return xy; } } public class myclass{ private static void myMethod(Test t,myint inf,int y){ int x=inf.returnit(t, y); System.out.println(x+""); } public static void main(String[] args){ myMethod(new Test(4),Test::addNumbers,7); myMethod(new Test(4),Test::subtractNumbers,7); } }
输出将是:
11 -3
这是我能想象到的最简单的方式。 了解如何使用上述句型匹配返回类型和参数类型。 花些时间在上面。
这是界面
package learninglambdaexp; @FunctionalInterface public interface TempInterface { public boolean validTemp(Temperature temp); }
这是class级
package learninglambdaexp; public class Temperature { private int temp; public Temperature(int temp) { this.temp = temp; } public boolean isEvenTemp() { return temp % 2 == 0; } public boolean isOddTemp(){ return !isEvenTemp(); } }
这是使用主方法的类
package learninglambdaexp; import java.util.ArrayList; import java.util.List; public class AnotherMainClass { public static void main(String[] args) { List tempCollection = new ArrayList<>(); tempCollection.add(new Temperature(100)); tempCollection.add(new Temperature(20)); tempCollection.add(new Temperature(30)); tempCollection.add(new Temperature(40)); tempCollection.add(new Temperature(50)); tempCollection.add(new Temperature(60)); tempCollection.add(new Temperature(70)); int k1 = countVariation(tempCollection, Temperature::isEvenTemp); //int k2 = countVariation(Temperature::lowTemp); System.out.println(k1); // System.out.println(k2); } private static int countVariation(List tempCollection, TempInterface ti) { int count = 0; for (Temperature eachTemp : tempCollection) { if (ti.validTemp(eachTemp)) { // (eachTemp) -> {return eachTemp.isEvenTemp();}; count++; } } return count; } }
有一个论点更容易理解