Lambda表达式(一)---概念以及常用表达式介绍

Lambda表达式由参数、箭头和主体组成
(Apple a1,Apple a2)-> a1.getWeight().compareTo(a2.getWeight());
1.lambda是什么
可以把Lambda表达式理解为简洁的表示可传递的匿名函数一种方式:它没有名称,但是它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表

(String s)->s.length();         // 参数类型为Sting,返回值为int型;lambda 没有return语句,隐含return
(Apple a) ->a.getWeight()>150; //参数类型为Apple,返回值为boolean类型(判断苹果的重量是否大于150g)
(int x,int y)->{
       System.out.println("Result:");
       System.out.println(x+y);
 };                             //参数类型为两个int类型数据,没有返回值(void);lambda可以包含多行语句
()->42;                        //没有参数,返回值为int类型
(Apple a1,Apple a2) ->a1.getWeight().compareTo(a2.getWeight()); // 参数为2个Apple类型数据,返回值为int型

2.函数式接口:就是只定义一个抽象方法的接口

public interface Runnable{
    void run();
}

Lambda允许你直接以内联的形式为函数式接口的抽象方法提供实现并把整个表达式作为函数式接口的实例,即lambda是函数式接口一个具体实现的实例。

public static void main(String[] args){
        Runnable r1 = ()->System.out.println("Hello World 1");
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World 2");
            }
        };

        process(r1);   //使用lambda表达式
        process(r2);   //使用匿名类
        process(()->System.out.println("Hello world 3"));  //使用直接传递的lambda打印

}
public static void process(Runnable r){
        r.run();
}

关于@FunctionalInterface
该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

3.函数描述符:函数式接口的抽象方法的签名称为,这种抽象方法叫做函数描述符

常用函数式接口

4.常用函数式接口
(1)Predicate
函数描述符为: T->boolean 表示参数为泛型,返回值为boolean类型,当你需要表示一个需要涉及类型T的布尔表达式时,就可以使用这个接口。

//创建一个函数式接口
public interface Predicate<T> {
    boolean test(T t);
}
//抽象方法
public static <T> List<T> filter(List<T> list,Predicate<T> p){
        List<T> results = new ArrayList<>();
        for (T s:list){
            if(p.test(s)){
                results.add(s);
            }
        }
        return results;
}
//调用方法(分步骤)
Predicate<String> nonEmptyStringPredicate = (String s )-> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings,nonEmptyStringPredicate);
//也可以写成
List<String> nonEmpty = filter(listOfStrings, (String s )-> !s.isEmpty(););

注意:属于java.util.function.Predicate<T>
(2)Consumer
函数描述符为:T->void 表示参数类型为泛型,无返回值,当你需要访问T类型的对象,并对其执行某些操作,但不需要返回值时就使用这个接口。

//创建函数式接口
public interface Consumer<T> {
    void accept(T t);
}
//抽象方法
public static <T> void forEach(List<T> list,Consumer<T> c){
        for(T i:list){
            c.accept(i);
        }
}
//调用方法
forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System.out.println(i));

注意:属于java.util.function.Consumer<T>
(3)Function
函数描述符:T->R,表示参数类型为泛型,返回值类型也为泛型,当你需要将输入的对象的信息映射到输出就可以使用这个接口,比如输入一个对象“苹果”,想要得到它的重量,就可以使用这个函数。换句话说就是输入一个泛型,可以得到另一个泛型的值。

//创建函数式接口
public interface Function<T,R> {
    R apply(T t);
}
//抽象方法
public static <T,R> List<R> map(List<T> list,Function<T,R> f){
            List<R> result = new ArrayList<>();
            for(T s:list){
                result.add(f.apply(s));
            }
            return result;
}
//调用方法
List<Integer> list =map(Arrays.asList("Predicate","Consumer","Function"),(String s)->s.length());

注意:属于java.util.function.Function<T,R>
5.原始类型特化
java有两种类型,引用类型和基本类型,由于泛型只能绑定到引用类型,这是由于泛型内部的实现方式导致的。而java中又有一个自动装箱和自动拆箱机制 ,这两种操作是自动完成的,所以我们使用上面提到的函数式接口时,就会在性能上面付出很大的代价。
装箱:将原始类型(基本类型)转换为对应的引用类型
拆箱:将引用类型转换为对应的基本类型
回顾下之前的知识:基本数据类型和引用类型的区别主要在于基本数据类型是分配在栈上的,而引用类型是分配在堆上的
比如看下面一段代码:

Predicate<Integer> oddNumbers= (Integer i) ->i%2==1;
oddNumbers.test(1000);

这段代码就将参数10000自动装箱到一个Integer对象中,这时候我们要避免将int型自动装箱至Integer对象中,就可以使用Predicate<T>的原始类型特化接口IntPredicate

IntPredicate newNumbers=(int i)->i%2==0;
newNumbers.test(1000);

这段代码中参数1000仍为int类型。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容