2014-09-24 73 views
2

我只是尝试了很少的java-8函数式编程,我对lamda表达式的行为几乎没有怀疑。我试图用简单的命令模式来解释下面的问题。Java-8 lambda表达式与函数接口的行为

public interface Editor { 
    public void open(); 
    public void close(); 
// public void save(); 

} 

编辑器实现

public class MyEditor implements Editor { 

    @Override 
    public void open() { 
     System.out.println("...opening"); 

    } 

    @Override 
    public void close() { 
     System.out.println("...closing"); 
    } 

} 

接口行动

// this is actually a @FunctionalInterface 
public interface Action { 
    public void perform(); 

} 

可操作的项目。

public class Open implements Action { 

    private final Editor editor; 

    public Open(Editor editor) { 
     this.editor = editor; 
    } 

    @Override 
    public void perform() { 
     editor.open(); 
    } 

// Similarly Close implements Action... 

...

宏来运行所有的动作。

public class Macro { 

    private final List<Action> actions; 

    public Macro() { 
     actions = new ArrayList<>(); 
    } 

    public void record(Action action) { 
     actions.add(action); 
    } 

    public void run() { 
     actions.forEach(Action::perform); 
    } 
} 

现在运行宏是interesing部分的地方。

public class RunMacro { 
    public static void main(String[] args) { 
     Editor editor= new MyEditor(); 
     Macro macro = new Macro(); 
     macro.record(() -> editor.open());// Line 4 
     macro.record(new Close(editor)); // Line 5 
     macro.run(); 
    } 
} 

我的问题是,4号线的运行,如何Java的理解,创造一个instanceof打开,并将其添加到宏中。简而言之,lamdba表达式的行为与第5行的行为相同。整个模式通过lambda表达式变得更简单但是使用OOPS进行函数式编程是否使开发处于非常抽象的级别或不太冗长?

礼貌的问题:O'Reilly Media公司:Java的8个Lamdbas

可以在任何一个请澄清这一点?

回答

7

Java如何理解创建一个instanceof Open并将其添加到宏?

您应该阅读java教程的Lambda Expressions中的Target Typing部分。 当你写道:

macro.record(() -> editor.open()); 

你不是在创造开放类的一个实例。您没有创建生成的匿名类的实例。

请参阅Translation strategy部分Translation of Lambda Expressions

代替生成字节代码创建实现lambda表达式(如,要求内部类的构造函数)的对象,我们描述了一种配方用于构建拉姆达,和代表实际施工的语言运行时。该配方编码在invokedynamic指令的静态和动态参数列表中。


你也可以采取优势的Java 8 method references的,并再次简化代码:

Editor editor= new MyEditor(); 
    Macro macro = new Macro(); 
    macro.record(editor::open); 
    macro.record(editor::close); 
    macro.run(); 

你最后可能会删除Action接口,并使用Runnable之一。这允许例如使用java.util.concurrent的所有东西,如Executor,新的Java承诺:CompletableFuture ...

+1

是啊!这是我正在寻找的,谢谢(: – chaosguru 2014-09-24 08:07:30

+0

谢谢(:这是更多的声明方式 – chaosguru 2014-09-24 08:17:21

+1

)对,我真的很喜欢方法引用和java 8引入了很多伟大的东西,没有失去它的简单性更大的java版本 – gontard 2014-09-24 08:20:10

0

Lambda构造是一个非常可读的替代品,它是Java语言的长期部分构造:匿名类。事实上,关于你的意图,你可以将lambda表达式看作是一个匿名类,尽管技术上有很大的不同。

只需添加第三个变种作为你的record方法:

macro.record(new Action() { 
    @Override public void perform() { editor.open(); } 
}); 

这里要传递一个匿名类的一个实例(的Action一个子类)的记录方法。这是lambda表达式是相同的:

macro.record(() -> editor.open()); 

对于这两个变种,你甚至不需要Open类。尝试一下,并从源代码中删除它。

+0

好吧,我明白了,谢谢你的阐述。 – chaosguru 2014-09-24 08:05:38