public interface MyFunc<T> {
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 <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;
//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()
与功能界面中的func()
兼容。sameTemp()
方法已在功能界面的func()
上实施。count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89));
正在运作请分别解释所有要点。
答案 0 :(得分:6)
HighTemp::lessThanTemp
的等效 lambda表达式是
(highTemp1, highTemp2) -> {
return highTemp1.lessThanTemp(highTemp2);
}
这是名为Reference to an Instance Method of an Arbitrary Object of a Particular Type
的Java8
的功能之一
考虑以下示例,
interface FIface<T> {
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 <T> int checkCall(T t1, T t2, FIface<T> 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);
}
}
<强>输出强>
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)
答案 1 :(得分:2)
首先,我不是专业程序员。我也非常难以理解所谓的&#34; 对特定类型的任意对象的实例方法的引用 &#34;我认为这可能对从谷歌搜索来到这里的人有所帮助
我在lambda表达的帮助下理解了一点。
在代码HighTemp::lessThanTemp
中,Lambda表达式看起来像(x,y)->{x.lessThanTemp(y);}
用这个lambda表达式替换方法引用会产生相同的结果。上面的Lambda表达式或方法引用都告诉接口方法要做什么。
当您使用方法引用时,它告诉接口方法使用给定类中的refer方法来执行其功能。因此,如果您将HighTemp::lessThanTemp
转换为英语单词,它会听起来像&#34; 实现lessThanTemp
方法形成类HighTemp
作为接口函数的实现&#34 ;.正如您可能已经注意到的那样,返回类型和参数类型应该是兼容的。否则您无法实现接口。
我会提供另一个简单的示例代码。更多示例有助于理解这一概念。
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 x-y;
}
}
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
这是我能想象到的最简单的方式。了解如何使用上述句型匹配返回类型和参数类型。花些时间在上面。
答案 2 :(得分:0)
这是界面
package learninglambdaexp;
@FunctionalInterface
public interface TempInterface {
public boolean validTemp(Temperature temp);
}
这是班级
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<Temperature> 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<Temperature> tempCollection, TempInterface ti) {
int count = 0;
for (Temperature eachTemp : tempCollection) {
if (ti.validTemp(eachTemp)) { // (eachTemp) -> {return eachTemp.isEvenTemp();};
count++;
}
}
return count;
}
}
有一个论点更容易理解
答案 3 :(得分:0)
Java 8允许我们使用称为方法引用的::
直接引用具有类和方法名称的方法。
java中有四种不同的方法引用方式
(s) -> System.out.println(s)
System.out::println
有关更多详细信息,请访问What is method reference in java?
答案 4 :(得分:0)
请纠正我,如果我错了,但是我对这种类型的方法引用(对特定类型的任意对象的实例方法的引用)的思考方式是:一个方法引用(在这种情况下为 counter 方法),将创建实现 MyFunc 接口的匿名类的实例。然后,在这个匿名类中,我们重写了传递两个参数的 func 方法。然后在 func 方法中,如下调用 lessThanTemp 方法:
v1.lessThanTemp(v2);
所以对我来说,这个概念看起来像这样:
public class Demo {
public static void main(String[] args) {
AnonymousClass an = new AnonymousClass();
System.out.println(an.apply(new SomeClass(3), 4));
}
}
interface SomeInterface {
int apply(SomeClass obj, int n);
}
class SomeClass {
private int n;
SomeClass(int n) {
this.n = n;
}
int add(int n) {
return this.n + n;
}
}
class AnonymousClass implements SomeInterface {
@Override
public int apply(SomeClass o, int n) {
return o.add(n);
}
}