Lambda 表达式有何用处?如何使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lambda 表达式有何用处?如何使用相关的知识,希望对你有一定的参考价值。

参考技术A 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。这一用法跟所谓 λ 演算(题目说明里的维基链接)的关系,有点像原子弹和质能方程的关系,差别其实还是挺大的。

不谈形式化的 λ 演算,只说有实际用途的匿名函数。先举一个普通的 Python 例子:将一个 list 里的每个元素都平方:
map( lambda x: x*x, [y for y in range(10)] )

这个写法要好过
def sq(x):
return x * x

map(sq, [y for y in range(10)])

,因为后者多定义了一个(污染环境的)函数,尤其如果这个函数只会使用一次的话。而且第一种写法实际上更易读,因
为那个映射到列表上的函数具体是要做什么,非常一目了然。如果你仔细观察自己的代码,会发现这种场景其实很常见:你在某处就真的只需要一个能做一件事情的
函数而已,连它叫什么名字都无关紧要。Lambda 表达式就可以用来做这件事。

进一步讲,匿名函数本质上就是一个函数,它所抽象出来的东西是一组运算。这是什么意思呢?类比
a = [1, 2, 3]


f = lambda x : x + 1

,你会发现,等号右边的东西完全可以脱离等号左边的东西而存在,等号左边的名字只是右边之实体的标识符。如果你能习惯 [1, 2, 3] 单独存在,那么 lambda x : x + 1 也能单独存在其实也就不难理解了,它的意义就是给「某个数加一」这一运算本身。

现在回头来看 map() 函数,它可以将一个函数映射到一个可枚举类型上面。沿用上面给出的 a 和 f,可以写:
map(f, a)

也就是将函数 f 依次套用在 a 的每一个元素上面,获得结果 [2, 3, 4]。现在用 lambda 表达式来替换 f,就变成:
map( lambda x : x + 1, [1, 2, 3] )

会不会觉得现在很一目了然了?尤其是类比
a = [1, 2, 3]
r = []
for each in a:
r.append(each+1)

这样的写法时,你会发现自己如果能将「遍历列表,给遇到的每个元素都做某种运算」的过程从一个循环里抽象出来成为一个函数 map,然后用 lambda 表达式将这种运算作
为参数传给 map 的话,考虑事情的思维层级会高出一些来,需要顾及的细节也少了一点。Python 之中,类似能用到 lambda
表达式的「高级」函数还有 reduce、filter 等等,很多语言也都有这样的工具(不过这些特性最好不要在 Python 中用太多,原因详见 的评论部分)。这种能够接受一个函数作为参数的函数叫做「高阶函数」(higher-order function),是来自函数式编程(functional programming)的思想。


其他很多语言相比,Python 的 lambda 限制多多,最严重的当属它只能由一条表达式组成。这个限制主要是为了防止滥用,因为当人们发觉
lambda 很方便,就比较容易滥用,可是用多了会让程序看起来不那么清晰,毕竟每个人对于抽象层级的忍耐 / 理解程度都有所不同。

API是什么?有何用处,其中常用类

  API(application programming interface)
        如何在新项目中使用原来的类
            如何生产:
            1.打开原项目
            2.项目名->右键->export->java-JAR file
            3.选择要打包的类
            4.JAR file:选择生成的jar包在什么位置(自己写文件名)
            5.完成,会在指定位置有一个.jar包

            如何使用:
            1.新建一个项目,创建类写个main方法
            2.在新项目中新建一个lib文件夹(folder)
            3.复制刚才导出的.jar包,粘贴到lib文件中
            4.右键选择lib文件夹中的.jar包->build path->add to build path
            5.直接在项目的所有类中使用原来的类了
        
        常用包:
            Java.lang:语言包,最基础的包
            java.util:集合框架,帮助类
            java.io:文件操作的包
            javax.swing、java.awt:java的图形化界面
            java.sql:用来连接数据库的包
            java.net:用来对网络进行操作

    
        ==:比较的是值是否相等
        普通类型:比较的就是实际的内容
        引用类型:还是比较值,但值的实际内容是地址,所以比较的是地址
        Scanner输入的字符串是对象,不是字符串常量。
        “abc”.intern()检查字符串池里是否存在“abc”这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把“abc”添加到字符串池中,然后再返回它的引用
        
        int a1=1;
        Integer b1 =new Integer (1);
            a1==b1 :不成立,它们是不同的数据类型 (JDK1.5以上为true,在int类型数据与Integer类型数据作比较时,Integer类型数据会自动转换为int类型数据,因此,在两种类型作比较时,只要值相等,即相等)
        
        Object中的equals就是用==来实现的
            public boolean equals(Object obj)
                return (this == obj);
            

            
        String类
        String类位于java.lang包中
        length()方法,确定字符串的长度
        equals( )方法,比较存储在两个字符串对象的内容是否一致,判断变量和字符是否相等,用字符.equals(变量)
        equalsIgnoreCase()方法,两个字符串进行比较时,忽略大小写不一致的情况。
        toLowerCase()方法,将字符串中所有英文字母改为小写。
        toUpperCase( )方法,将字符串中所有英文字母改为大写。
        
        concat与"+"用法相同
        A.concat(B):B字符串将被连接到A字符串后面
            String name="sss";
            String s=new String("rr");
            System.out.println(s+name);
            System.out.println(s.concat(name));
            运行结果:
                rrsss
                rrsss
        
        搜索第一个出现的字符ch(或字符串value),-1表示未找到
        public int indexOf(int ch)
        public int indexOf(String value)
    
        搜索最后一个出现的字符ch(或字符串value),-1表示未找到
        public int lastIndexOf(int ch)
        public int lastIndexOf(String value)

        返回一个前后不含任何空格的调用字符串的副本
        public String trim()
        
        提取beginindex和endindex之间的字符串部分(包含前面,不包含后面)
        public String substring(int beginindex, int endindex)
        
        提取从位置索引开始的字符串部分
        public String substring(int index)
        
        split("切割标志")方法,将一个字符串分割为子字符串,结果作为字符串数组返回,但切割标志(不包括符号“.”)不在字符串数组中。
        
        
        StringBuffer类:String类的增强版
        StringBuffer声明:
            StringBuffer sb=new StringBuffer();
            StringBuffer sb2=new StringBuffer("字符串");
            
        StringBuffer的使用:
            sb.toString(); 将StringBuffer类型转化为String类型
            sb.append("aa"); 在sb字符串后面追加字符串aa
            sb.length();获取字符串的长度
            sb.insert(length,"a");在字符串sb中添加字符串a(从后往前每隔length位添加字符串a)
            

        Date类(1000ms=1s)
            获取系统当前时间是一个长整型数据Long, Date 类实际上只是一个包裹类, 它包含的是一个长整型数据,表示的是从GMT(格林尼治标准时
        间)1970年, 1 月 1日00:00:00这一刻之前或者是之后经历的毫秒数.
        Date类中专门用于将日期格式化为字符串的方法:
            toDateString() -以特定于实现的格式显示星期几、月、日和年;
            toTimeString() -以特定于实现的格式显示时、分、秒和时区;
            toLocaleDateString() -以特定于地区的格式显示星期几、月、日和年;
            toLocaleTrimeString() -以特定于实现的格式显示时、分、秒;
            toUTCString() -以特定于实现的格式完整的UTC日期。
        注:与toLocaleString()和toString()方法一样,以上这些字符串格式方法的输出也是因浏览器而异的,因此没有哪一个方法能够用来在用户界面中显示一致的日期信息。
        
        getTime() -返回表示日期的毫秒数;与valueOf()方法返回的值相同
        setTime(毫秒) -以毫秒数设置日期,会改变整个日期
        getFullYear() -取得4位数的年份(如2007而非仅07)
        getMonth() -返回日期中的月份,其中O表示一月,11表示十二月
        getDate() -返回日期月份中的天数(1到31)
        getHours() 返回日期中的小时数(0到23)
        getDay() -返回日期中星期的星期几(其中0表示星期日,6表示星期六)
        getMinutes() -返回日期中的分钟数(0到59)
        setDate(日) -设置日期月份中的天数。如果传人的值超过了该月中应有的天数,则增加月份
        setHours(时)-设置日期中的小时数。传人的值超过了23则增加月份中的天数
        setMinutes(分) -设置日期中的分钟数。传入的值超过59则增加小时数
        
        
        DateFormat:日期格式化类(抽象类)(java.text.DateFormat )
        String format(Date date)  方法用于格式化时间
        static DateFormat getDateInstance()   获取日期的DateFormat 对象
        static DateFormat getDateTimeInstance()   获取日期-时间的DateFormat 对象
        static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle)获取给定日期和时间格式化风格 DateFormat对象(可选参数 short,full, long, medium )
            CST:中央标准时间
            System.out.println(DateFormat.getDateInstance().format(new Date()));
            System.out.println(DateFormat.getTimeInstance().format(new Date()));
            System.out.println(DateFormat.getDateTimeInstance().format(new Date()));
            System.out.println(DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG).format(new Date()));
            System.out.println(DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM).format(new Date()));
            System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL).format(new Date()));
            System.out.println(DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT).format(new Date()));
            运行结果:
                2019-4-12
                11:22:29
                2019-4-12 11:22:29
                2019年4月12日 上午11时22分29秒
                2019-4-12 11:22:29
                2019年4月12日 星期五 上午11时22分29秒 CST
                19-4-12 上午11:
        
        SimpleDateFormat类:(java.text.SimpleDateFormat )
            只要通过向SimpleDateFormat(DateFormat的子类)的构造函数传递格式字符串“EEEE-MM-dd-yyyy"(EEEE是星期, MM是月, dd是日, yyyy是年. 字符的个数决定了日期
        是如何格式化的.传递"EE-MM-dd-yyyy"会显示 星期五-02-27-2009),然后调用DateFormat(Date date)方法,得到想要的格式。
        
        public Date parse(String source) 将一个字符串转换成时间类
        Date now = new Date();自动获得当前系统的日期和时间(构造函数在内部使用了System.currentTimeMillis() 方法来从系统获取日期)。
        setTime(long time)
          设置此 Date 对象,以表示 1970 年 1 月 1 日 00:00:00 GMT 以后 time 毫秒的时间点。
        after(Date when)
          测试此日期是否在指定日期之后。
        before(Date when)
          测试此日期是否在指定日期之前。
        clone()
          返回此对象的副本。
        
        字母  日期或时间元素  表示  示例  
        y  年  Year  1996; 96  
        M  年中的月份  Month  July; Jul; 07  
        w  年中的周数  Number  27  
        W  月份中的周数  Number  2  
        D  年中的天数  Number  189  
        d  月份中的天数  Number  10  
        F  月份中的星期  Number  2  
        E  星期中的天数  Text  Tuesday; Tue  
        a  Am/pm 标记  Text  PM  
        H  一天中的小时数(0-23)  Number  0  
        k  一天中的小时数(1-24)  Number  24  
        K  am/pm 中的小时数(0-11)  Number  0  
        h  am/pm 中的小时数(1-12)  Number  12  
        m  小时中的分钟数  Number  30  
        s  分钟中的秒数  Number  55  
        S  毫秒数  Number  978  
        z  时区  General time zone  Pacific Standard Time; PST; GMT-08:00  
        Z  时区  RFC 822 time zone  -0800  
        
        
        Calendar 类:(抽象类,它有一个子类GregorianCalendar)
        Calendar calendar=Calendar.getInstance(); 获取Calendar对象
        calendar.get(Calendar.YEAR)  获取年
        calendar.get(Calendar.MONTH) + 1)  获取月(月是从0开始,0代表一月)
        calendar.get(Calendar.DAY_OF_WEEK) + 1)  获取星期几(星期是从1开始,星期天是1)
        calendar.add(Calendar.YEAR, 2);  年上加2年

以上是关于Lambda 表达式有何用处?如何使用的主要内容,如果未能解决你的问题,请参考以下文章

如何用 C# 中的函数语句替换 for 循环?

API是什么?有何用处,其中常用类

如何使用 lambda 表达式检查元素是不是存在?

如何取消订阅使用 lambda 表达式的事件?

如何取消订阅使用 lambda 表达式的事件?

如何在 Enumerable.Distinct() 中使用 lambda 表达式 [重复]