void anonymousClass() {
final Server server = new HttpServer();
waitFor(new Condition() {
@Override
public Boolean isSatisfied() {
return !server.isRunning();
}
}
下面的代码用 Lambda 表达式实现相同的功能:
void closure() {
Server server = new HttpServer();
waitFor(() -> !server.isRunning());
}
其实,上面的waitFor方法,更接近于下面的代码的描述:
class WaitFor {
static void waitFor(Condition condition) throws
InterruptedException {
while (!condition.isSatisfied())
Thread.sleep(250);
}
}
一些理论上的区别
实际上,上面的两种方法的实现都是闭包,后者的实现就是Lambda 表示式。这就意味着两者都需要持有运行时的环境。在 Java 8 之前,这就需要把匿名类所需要的一切复制给它。在上面的例子中,就需要把 server 属性复制给匿名类。
因为是复制,变量必须声明为 final 类型,以保证在获取和使用时不会被改变。Java 使用了优雅的方式保证了变量不会被更新,所以我们不用显式地把变量加上 final 修饰。
public interface FunctionalInterfaceExample {
// compiles ok
}
如果加上@FunctionalInterface注解,则会编译错误:
@FunctionalInterface // <- error here
public interface FunctionalInterfaceExample {
// doesn't compile
}
编译器就会报错,错误的详细信息为“Invalid '@FunctionalInterface' annotation; FunctionalInterfaceExample is not a functional interface”。意思是没有定义一个单一的抽象方法。 而如果我们定义了两个抽象方法会如何?
@FunctionalInterface
public interface FunctionalInterfaceExample {
void apply();
void illegal(); // <- error here
}
编译器再次报错,提示为"multiple, non-overriding abstract methods were found"。所以,一旦使用了此注解,则在接口里只能定义一个抽象方法。
@FunctionalInterface
interface A {
abstract void apply();
}
interface B extends A {
如果你想看起来更加清晰,可以复写父类的方法:
@FunctionalInterface
interface A {
abstract void apply();
}
interface B extends A {
@Override
abstract void apply();
}
我们可以用下面的代码来测试一下上面的两个接口是否为函数式接口:
@FunctionalInterface
public interface A {
void apply();
}
public interface B extends A {
@Override
void apply();
}
public static void main(String... args) {
A a = () -> System.out.println("A");
B b = () -> System.out.println("B");
a.apply(); // 打印:A
b.apply(); // 打印:B
}
public void usage() {
List list = new ArrayList<>();
initialise(list, String::new);
}
private void initialise(List list, Factory factory) {
for (int i = 0; i < 10; i++) {
list.add(factory.create());
}
}
到现在为知,我们演示的都是无参的构造方法的引用,如果是带有参数的构造方法的引用该如何处理呢? 当有多个构造函数时,使用相同的语法,但编译器计算出哪个构造函数是最佳匹配。它基于目标类型和推断功能接口,它可以用来创建该类型。 例如,我们有个 Person 类,它有一个多个参数的构造方法。
class Person {
public Person(String forename, String surname, LocalDate
birthday, Sex gender, String emailAddress, int age) {
// ...
}
回到上面的例子,我们可以如下使用:
initialise(people, () -> new Person(forename, surname, birthday,
gender, email, age));
但是如果想使用这个构造方法引用,则需要 Lambda 表达式提供如下参数:
initialise(people, () -> new Person(forename, surname, birthday,
gender, email, age));
public void lambdaExample() {
function("value", new Function() {
@Override
// takes the argument as a parameter, doesn't need to close
over it
public String apply(String x) {
return x.toString();
}
});
}
web.xml报错
The content of element type "web-app" must match "(icon?,display-
name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,s
JUnit4:Test文档中的解释:
The Test annotation supports two optional parameters.
The first, expected, declares that a test method should throw an exception.
If it doesn't throw an exception or if it
借鉴网上的思路,用java实现:
public class NoIfWhile {
/**
* @param args
*
* find x=1+2+3+....n
*/
public static void main(String[] args) {
int n=10;
int re=find(n);
System.o
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory。
分析:这是不同系统编码格式引起的:在windows系统中编辑的.sh文件可能有不可见字符,所以在Linux系统下执行会报以上异常信息。
解决:
1)在windows下转换:
利用一些编辑器如UltraEdit或EditPlus等工具
Binary search tree works well for a wide variety of applications, but they have poor worst-case performance. Now we introduce a type of binary search tree where costs are guaranteed to be loga