在Java 8中,方法可以作为Lambda表达式来创建,并且可以通过引用来传递(只需在引擎盖下做一点工作)。网上有很多关于Lambdas被创建并与方法一起使用的例子,但没有关于如何使一个方法接受Lambda作为参数的例子。这方面的语法是什么?
MyClass.method((a, b) -> a+b);
class MyClass{
//How do I define this method?
static int method(Lambda l){
return l(5, 10);
}
}
Lambdas纯粹是一种调用站点结构:Lambda的接收者不需要知道有Lambda的参与,相反,它接受一个带有适当方法的接口。
换句话说,你定义或使用一个功能接口(即一个具有单一方法的接口),接受并返回你想要的东西。
为此,Java 8在java.util.function
中提供了一组常用的接口类型(感谢Maurice Naftalin提供的关于JavaDoc的提示)。
对于这个特定的用例,有java.util.function.IntBinaryOperator
,有一个int applyAsInt(int left, int right)
方法,所以你可以这样写你的方法
。
static int method(IntBinaryOperator op){
return op.applyAsInt(5, 10);
}
但你也可以定义你自己的接口,像这样使用它。
public interface TwoArgIntOperator {
public int op(int a, int b);
}
//elsewhere:
static int method(TwoArgIntOperator operator) {
return operator.op(5, 10);
}
使用你自己的接口的好处是,你可以有更清楚地表明意图的名字。
要使用Lambda表达式,你需要创建自己的函数式接口,或者使用Java函数式接口进行需要两个整数并返回值的操作。IntBinaryOperator。
使用用户定义的函数接口
interface TwoArgInterface {
public int operation(int a, int b);
}
public class MyClass {
public static void main(String javalatte[]) {
// this is lambda expression
TwoArgInterface plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.operation(10, 34));
}
}
使用Java功能接口
import java.util.function.IntBinaryOperator;
public class MyClass1 {
static void main(String javalatte[]) {
// this is lambda expression
IntBinaryOperator plusOperation = (a, b) -> a + b;
System.out.println("Sum of 10,34 : " + plusOperation.applyAsInt(10, 34));
}
}
我创建的其他例子是这里 。
对于参数不超过2个的函数,可以不定义自己的接口而通过。 例如,
class Klass {
static List<String> foo(Integer a, String b) { ... }
}
class MyClass{
static List<String> method(BiFunction<Integer, String, List<String>> fn){
return fn.apply(5, "FooBar");
}
}
List<String> lStr = MyClass.method((a, b) -> Klass.foo((Integer) a, (String) b));
在BiFunction<Integer,String,List<String>>
中,Integer
和String
是其参数,List<String>
是其返回类型。
对于只有一个参数的函数,可以使用Function<T,R>
,其中T
是其参数类型,R
是其返回值类型。
参考这个page,了解Java已经提供的所有接口。
有一个支持Lambda的Java 8 JavaDocs的公共网络访问版本,链接自http://lambdafaq.org/lambda-resources。 (这显然应该是对Joachim Sauer的回答的评论,但我无法进入我的SO账户,因为我需要名誉积分来添加评论)。) lambdafaq网站(我负责维护)回答了这个问题和其他许多Java-lambda问题。
NB 这个答案是在Java 8 GA文档公开可用之前写的。但我还是保留了下来,因为Lambda FAQ可能对人们学习Java 8中引入的功能仍有帮助。
如果有人上网查,好的方法是用java.util.function.BiConsumer
。
例如:
Import java.util.function.Consumer
public Class Main {
public static void runLambda(BiConsumer<Integer, Integer> lambda) {
lambda.accept(102, 54)
}
public static void main(String[] args) {
runLambda((int1, int2) -> System.out.println(int1 + " + " + int2 + " = " + (int1 + int2)));
}
。
Import java.util.function.Consumer
public Class Main {
public static void runLambda(BiConsumer<Integer, Integer> lambda) {
lambda.accept(102, 54)
}
public static void main(String[] args) {
runLambda((int1, int2) -> System.out.println(int1 + " + " + int2 + " = " + (int1 + int2)));
}
打印的内容是: 166
在我看来,最合理的解决方案是定义一个 "回调 "接口。
interface Callback {
void call();
}
然后在你要调用的函数中使用它作为参数。
void somewhereInYourCode() {
method(() -> {
// You've passed a lambda!
// method() is done, do whatever you want here.
});
}
void method(Callback callback) {
// Do what you have to do
// ...
// Don't forget to notify the caller once you're done
callback.call();
}
lambda不是一个特殊的接口、类或其他任何你可以自己声明的东西。
Lambda
只是给() -> {}
的特殊语法,它允许在传递单方法接口作为参数时有更好的可读性。
它的设计是为了取代这个.Lambda`。
method(new Callback() {
@Override
public void call() {
// Classic interface implementation, lot of useless boilerplate code.
// method() is done, do whatever you want here.
}
});
所以在上面的例子中,Callback
不是**的lambda,它只是一个普通的接口。
lambda
是你可以用来实现它的快捷语法的名字。
Lambda表达式可以作为一个参数传递,为了将lambda表达式作为一个参数传递,参数的类型(接受lambda表达式作为参数)必须是函数接口类型。
如果有一个函数接口----------。
interface IMyFunc {
boolean test(int num);
}
还有一个过滤方法,只有当int大于5时,才会将其添加到列表中。 请注意,过滤方法的参数之一是函数接口IMyFunc。 在这种情况下,lambda表达式可以作为方法参数的参数传递。
public class LambdaDemo {
public static List<Integer> filter(IMyFunc testNum, List<Integer> listItems) {
List<Integer> result = new ArrayList<Integer>();
for(Integer item: listItems) {
if(testNum.test(item)) {
result.add(item);
}
}
return result;
}
public static void main(String[] args) {
List<Integer> myList = new ArrayList<Integer>();
myList.add(1);
myList.add(4);
myList.add(6);
myList.add(7);
// calling filter method with a lambda expression
// as one of the param
Collection<Integer> values = filter(n -> n > 5, myList);
System.out.println("Filtered values " + values);
}
}
你可以使用上面提到的功能接口。 以下是一些例子
Function<Integer, Integer> f1 = num->(num*2+1);
System.out.println(f1.apply(10));
Predicate<Integer> f2= num->(num > 10);
System.out.println(f2.test(10));
System.out.println(f2.test(11));
Supplier<Integer> f3= ()-> 100;
System.out.println(f3.get());
希望能帮到你
嗯,这很简单。 lambda表达式的目的是实现功能接口。 它是只有一个方法的接口。 [这里是一篇关于预定义和遗留功能接口的文章][1] 。
[1]: http://www.baeldung.com/java-8-functional-interfaces
总之,如果你想实现自己的功能接口,就做吧。 只是举个简单的例子。
public interface MyFunctionalInterface {
String makeIt(String s);
}
所以让我们创建一个类,在这个类中我们将创建一个方法,它接受MyFunctionalInterface的类型。
public class Main {
static void printIt(String s, MyFunctionalInterface f) {
System.out.println(f.makeIt(s));
}
public static void main(String[] args) {
}
}
最后你应该做的是将MyFunctionalInterface的实现传递给我们定义的方法'。
public class Main {
static void printIt(String s, MyFunctionalInterface f) {
System.out.println(f.makeIt(s));
}
public static void main(String[] args) {
printIt("Java", s -> s + " is Awesome");
}
}
就是这样!
Lambda不是一个对象,而是一个功能接口。 我们可以使用@FuntionalInterface作为注解来定义尽可能多的功能接口。
@FuntionalInterface
public interface SumLambdaExpression {
public int do(int a, int b);
}
public class MyClass {
public static void main(String [] args) {
SumLambdaExpression s = (a,b)->a+b;
lambdaArgFunction(s);
}
public static void lambdaArgFunction(SumLambdaExpression s) {
System.out.println("Output : "+s.do(2,5));
}
}
輸出內容如下
Output : 7
Lambda表达式的基本概念是定义你自己的逻辑,但已经定义了Arguments。 因此,在上面的代码中,你可以将do函数的定义从加法改为任何其他定义,但你的参数限制为2个。
做以下工作.
你已经声明了method(lambda l)
。
你要做的就是创建一个名称为lambda
的接口,并声明一个抽象方法。
public int add(int a,int b);
方法名称在这里并不重要...
所以当你调用MyClass.method( (a,b)->a+b)
时
这个实现(a,b)->a+b
将被注入到你的接口add方法中.所以每当你调用l.add
时,它将采用这个实现并执行a
和b
的加法,return l.add(2,3)
将返回5
。
在使用lambda作为参数时具有灵活性。 它使java中的函数式编程成为可能。 基本语法是
param -> method_body
以下是一种方法,你可以定义一个以功能接口(使用lambda)为参数的方法。
a.
如果你想定义一个在函数式接口中声明的方法。
例如,将功能接口作为参数/参数给一个从main()
调用的方法。
@FunctionalInterface
interface FInterface{
int callMeLambda(String temp);
}
class ConcreteClass{
void funcUsesAnonymousOrLambda(FInterface fi){
System.out.println("===Executing method arg instantiated with Lambda==="));
}
public static void main(){
// calls a method having FInterface as an argument.
funcUsesAnonymousOrLambda(new FInterface() {
int callMeLambda(String temp){ //define callMeLambda(){} here..
return 0;
}
}
}
/***********Can be replaced by Lambda below*********/
funcUsesAnonymousOrLambda( (x) -> {
return 0; //(1)
}
}
>.FInterface fi = (x) ->。 FInterface fi = (x) -> { return 0; };
FInterface fi = (x ->); { return 0; }; >
funcUsesAnonymousOrLambda(fi);
在上面这里可以看到,lambda表达式如何用接口来代替。
上面解释了lambda表达式的一个特殊用法,还有更多。 参考 https://stackoverflow.com/questions/23451579/java-8-lambda-within-a-lambda-cant-modify-variable-from-outer-lambda
[1]: http://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html