1. Java匿名类
1.1 匿名内部类使用传进来的参数:
代码块1-1
public static List<Integer> CreateMyList(int[] a)
{
return new AbstractList<Integer>()
{
@Override
public Integer get(int index)
{
return a[index];
}
@Override
public int size()
{
return a.length;
}
};
}
new AbstractList() 方法创建了一个实现了 AbstractList 接口的匿名内部类,注意匿名内部类可以使用参数或者这个静态方法所在类的静态成员,但是参数不是成员,无法随时访问到,因此需要创建一个参数类型的成员,并在创建匿名内部类时初始化它。使用idea转换匿名类为内部类的功能,可以看出以上述方式创建的匿名内部类如下所示:
代码块1-2
private static class IntegerAbstractList extends AbstractList<Integer>
{
private final int[] a;
public IntegerAbstractList(int[] a) {this.a = a;}
@Override
public Integer get(int index)
{
return a[index];
}
@Override
public int size()
{
return a.length;
}
}
1.2 匿名内部类与lambda表达式
代码块1-3
@FunctionalInterface
interface LambdaTest<T>
{
T add( T a, T b);
//默认实现方法
default void print(T t){System.out.println(t);};
}
代码块1-4
@FunctionalInterface
interface LambdaTest<T>
{
T add( T a, T b);
//默认实现方法
default void print(T t){System.out.println(t);};
}
LambdaTest<Integer> testLambda=(a,b)->a+b;
LambdaTest<Integer> testAnonymous=new LambdaTest<Integer>()
{
@Override
public Integer add(Integer a, Integer b)
{
return a+b;
}
};
上面两种写法是等价的。
2.lambda表达式
如果一个接口有如下方法:
代码块2-1
@FunctionalInterface
interface Foo<T,R>
{
R foo(T...t);
}
那么可以用lambda表达式快速的生成一个实现Foo接口foo方法的匿名类。
注意Foo接口必须只有一个要实现的方法,有多个要实现的方法,是没有办法给这个接口类型赋予一个lambda表达式的。
为了避免这个接口有多个要实现的方法,可以使用注解@FunctionalInterface来限制这个接口要实现的方法只有一个。
代码块2-2
Foo<Integer foo=x->
{
Integer res=1;
for(Integer num:x)
{
res*=num;
}
return res;
}
lambda表达式的结构:
{params} ->{ {statement;[returnStatement]} }
对应一个有若干个参数且返回(也可以没有返回值)任意类型的一个接口方法的实现。
如果lambda表达式有若干个语句,且lambda表达式对应的要实现的接口方法有返回值,则需要显示地写一个return语句,否则可以不写。
注意,如果是以 类名::method且这个method是实例方法,那么得到的lambda表示式其实必然是接受一个以上的参数的,因为第一个参数必然是该对象本身,因此BigDecimal::add
方法
public BigDecimal add(BigDecimal augend);
和
@FunctionalInterface
public interface Foo<T,R>
{
R foo(T t1,T t2);
}
中的R接口的方法签名是一致的,所以下面的表达式是成立的:
Foo<BigDecimal,BigDecimal> foo = BigDecimal::add;