Java中的Lambda表达式
最近看到一段代码, 里面用到了lambda表达式。刚开始学习java语法的时候对于这些东西只是草草看了一下,以后也没再用,到现在都忘干净了。突然感觉自己的基础很薄弱呀,,,所以重新学了一下,特此记录。
一、什么是Lambda表达式?
Lambda表达式是一个匿名函数,所谓的匿名函数,就是没有名字的函数。在Java中,Lambda表达式的出现,对于代码的简洁,性能的提升都有很大的帮助。
二、Lambda表达式优点?
找了点资料:
1)提升了代码的简洁程度。不用写大量的匿名内部类了。
2)对于集合操作也得到了极大地改善
3) 可并行处理,充分利用了多核CPU的优势
三、具体Lambda表达式的使用
1)一个简单的例子:
List<Integer> list=Arrays.asList(1,2,3,4,5);
list.forEach((s)->{System.out.println(s);});
用for循环四五行代码的循环,在这用一句话就搞定了。list.forEach表示内部循环,它要求的lambda表达式是有输入参数没有返回值的。
lambda表达式具体语法:
由三部分组成:参数列表,->,函数体
(参数列表) -> {函数体; } 如何没有参数可以空着。
如果函数体重只有一行操作,也可以去掉分号,如下:
(s)-> System.out.println(s)
如果只有一个参数,也可以去掉括号,如下:
s-> System.out.println(s)
Lambda没有参数类型,因为它会自己根据上下文自动推断你的类型。Lambda表达式的类型叫做目标类型,它的目标类型是函数接口,函数接口一般用@FunctionalInterface标注出来,也可以不标注,函数接口其实也是一个接口,它与其他接口的区别是它内部只有一个方法。
自定义的函数接口:
@FunctionalInterface//这个接口要求有一个输入参数,但是没有返回值
interface MyInterface<T> {
public void show(T t);
}
//自定义函数接口的lambda表达式
MyInterface my=(c)->{
System.out.println(c);
};
//调用
my.show("next");
有了lambda表达式,就不用再使用匿名内部类了~
2)java内置的常用函数接口
大部分情况下不需要自己定义这些函数式接口,java的java.util.function包下已经有很多常用的函数接口了。
Function接口,代表一个函数,接受一个T类型的参数,并返回一个R类型的返回值。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
Predicte接口,传入一个参数,判断条件是否满足
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Consumer接口,传入一个参数,没有返回值,上面的例子就是这种接口
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Supplier接口,没有任何参数,有一个返回值。
@FunctionalInterface
public interface Supplier<T> {
T get();
}
3)Lambda表达式在集合中的使用-stream
流的设计相当于一根管道,集合是数据源,对流的一个操作返回一个流,然后对其进行操作,多个不同的流操作可以结合起来使用。
stream的特点:
1.不存储值:Streams不会存储值,它们从某个数据结构的流水线型操作中获取值
2.天生的函数编程特性:对Stream对象操作能得到一个结果,但是不会修改原始数据结构
3.Laziness-seeking(延迟搜索):Stream的很多操作如filter、map、sort和duplicate removal(去重)可以延迟实现,意思是我们只要检查到满足要求的元素就可以返回
4.可选边界:Streams允许Client取足够多的元素直到满足某个条件为止。而Collections不能这么做
例子:
List<String> list=new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("aaa");
list.add("aaac");
list.stream()//获取一个集合的流
.filter((s)->s.contains("a"))//挑选出所有带a的
.forEach(s-> System.out.println(s));//输出
List<String> list1=new ArrayList<>();
for (int i=1;i<100;i++){
list1.add(i+"");
}
list1.stream()
.map(i->new Integer(i))//将String转为int
.distinct()//去除重复的
.filter(i->i>=25&&i<=50)//找到所有在25--50区间的
.forEach(c-> System.out.println(c));//输出
stream还有很多的功能,具体的话还是多看文档吧。
4)方法引用:任何一个Lambda表达式都可以代表某个函数接口的唯一方法的匿名描述符。我们也可以使用某个类的某个具体方法来代表这个描述符,叫做方法引用
构造器引用:User::new
静态方法引用:Integer::parseInt
实例方法引用:String::length
Function<String,Integer> function=String::length;
System.out.println(function.apply("dasds"));
它相当于Function<String,Integer> function1=(c)->{return c.length();};
友情链接:
stream详细的介绍
stream教程
ps:渣渣一枚,如有不对请大佬指出~~