Lanmda表达式
Lambda表达式是给函数式接口(FunctionalInterface)的形参或变量赋值用的.
函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口的分类
-
消费型接口(Consumer)特点:有参无返回值
-
供给型接口(Supplier)特点:无参有返回值
-
判断型接口(Predicate)特点:返回值类型为布尔类型
-
功能型接口(Function) 特点:有参有返回值
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class TestLambda {
public static void main(String[] args) {
1、消费型接口
//consumer<T> : void accept<T t>
//集合java.lang.Collection系列的集合在java8之后增加了这样的方法:
// default void forEach(consumer<? super T> action)
ArrayList<Integer> a = new ArrayList<>();
a.add(1);a.add(2);a.add(3);a.add(4);a.add(5);
a.forEach((t)->System.out.print(t));
//输出结果为:12345
//其他的变形还有:
//BiConSumer<T t,U u> void accept(T t,U u) 二元的
//DoubleConSumer void accept(double value) double
//IntConSumer void accept(int value) Int
//LongConSumer void accept(Long value) Long
//ObjDoubleConSumer<T> void accept(T t,double value)
//ObjIntConSumer<T> void accept(T t,int value)
//ObjLongConSumer<T> void accept(T t,long value)
2、供给型接口
//Supplier<T> : T get()
//其他变形:
//BooleanSupplier boolean getAsBoolean()
//DoubleSupplier double getAsDouble()
//IntSupplier int getAsInt()
//LongSupplier long getAsLong()
//Stream流
//Stream<Double> stream = Stream.generate(()->Math.random());
//stream.forEach((t)->System.out.println(t));
3、判断型接口
//Predicate<T> boolean test(T t)
//eg:java.util.Collection<E>
//default boolean removeIf(Predicate<? super E> filter)
a.removeIf(t->t%3==0);
a.forEach((t)->System.out.print(t));
//输出结果为245
//其他变形:
//BiPredicate<T,U> boolean test(T t,U u)
//DoublePredicate boolean test(double value)
//IntPredicate boolean test(double value)
//DoublePredicate boolean test(double value)
//LongPredicate boolean test(long value)
4、功能型接口 有参有返回值
//Function<T,R> R apply(T t)
//其他变形:
//IntFunction<R> R apply(Int value)
//ToIntFunction<T> int apply(T value)
//LongToIntFunction int apply(long value)
//IntUnaryOperator int applyAsInt(int operand)
}
}
Lambd表达式的语法
lambda表达式的语法:
(形参列表)->{Lambda体}
若返回值不为void,lambda表达式内要有return语句,但只有一句,并且为return语句时,可以省略return;
应用举例
1、list.forEach((t)->System.out.print(t));
2、list.removeIf(t->t%3==0);
3、TreeSet<A> set = new TreeSet<> ((o1,o2)>Double.cpmpare(o1.getScore(),o2.getScore());
如果3中若成绩相同按照姓名排序则后面可以写成:
((o1,01)->o1.getScore()==o2.getSocre()?o1.getName()-o2.getName():
o1.getScore( )-o2.getScore())
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class TestLambda {
public static void main(String[] args) {
A aa = new A();
ArrayList<String> query = aa.query(t->t.equals("afei1"));
query.forEach(t->System.out.println(t));
}
}
class A{
private ArrayList<String> a;
public A() {
super();
this.a = a;
a= new ArrayList<>();
a.add("afei1");
a.add("afei2");
}
public ArrayList<String> query(Predicate<String> p){
ArrayList<String> res = new ArrayList<>();
for(String sub:a) {
if(p.test(sub)) {
res.add(sub);
}
}
return res;
}
}
Lambda表达式作用
lambda表达式可以减少代码的冗余量,相对于内部匿名类可读性增强
例如SAM接口:
SAM:Single Abstract Method
java.lang.Runnable:public void run()
√java.lang.Comparable<T>:public int compareTo(T t)
√java.lang.util.Comparator<T>:public int Compare(T t1,T t2)
java.lang.Iterable:public Iterable iterator();
java.lang.InvocationHandler:public Object invoke(Object proxy,Method method,Object[])
√java,io.FileFilter:public boolean accept(File pathnName)
按理说,只要有一个抽象方法的接口,都会加一个注解:@Functional Interface 【上面打勾的】
如果没有加该注解标记,将来有可能增加新的抽象方法,这样子的接口,建议谨慎使用lambda表达式