11-Java中常用的API

在这里插入图片描述

一切都是最好的安排,学会拥抱未知,做更好的自己。

1. 什么是API?

  • API (Application Programming interface) 应用程序编程接口。
  • 通俗来讲,就是Java已经帮我们写好了一些方法,我们直接拿过来用即可。

iodraw:https://www.iodraw.com/

API在线中文文档:https://www.matools.com/api/java8

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIGjTNo6-1656678744854)(常用的API.assets/image-20220630073311584.png)]

当然也可以IntelliJ 在IDEA中查看Java源码。


2. Object、Objects类

2.1 Object类

  • Object类位于java.lang包,在Java中所有的类都是直接或者间接继承该类。

  • Object类的方法是一切子类都可以使用的。

    Object类常用的方法:

方法名说明
public String toString()默认是返回当前对象在堆内存中的地址信息:类的全限定名@内存地址
public boolean equals(Object obj)默认是比较两个对象的地址是否相同(==),相同返回true,不同返回false
public final Class getClass()返回Class类型的对象
protected Object clone()创建并返回此对象的副本
public int hashCode()返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。

不同对象的 hashCode的值一般是不相同。但是,同一个对象的hashCode值肯定相同。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2lCmQ8Vb-1656678744856)(常用的API.assets/image-20220630080436586.png)]


2.2 Objects类

  • Objects类与Object还是继承关系,它位于java.util包,Objects类是JDK1.7之后开始有的。
  • 相比之下Objects中的equals()方法更加安全(多了个非空判断)。
public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

Objects类的常用方法:

方法名说明
public boolean equals(Object a,Object b)比较两个对象的地址是否相同,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比较
public static boolean isNull(Object obj)判断变量是否为null

3. Math类

  • Math类提供了一些数字运算的方法(如:指数,对数,平方根、三角函数等等),它是一个数学工具类不需要创建对象(因此构造器私有化)。

  • 使用:Math中许多成员都被static修饰了,直接用类名.xxx调用即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hw5VE1P2-1656678744858)(常用的API.assets/image-20220630083745346.png)]


4. System类

System的功能是通用的,都是直接用类名调用即可,所以System不能被实例化。

System类常用方法:

方法名说明
public static void exit(int status)终止当前运行的Java虚拟机,非零表示异常终止
public static native long currentTimeMillis()返回当前系统时间的毫秒数(时间戳)
public static void arraycopy(源数组,起始索引,目标数组,起始索引,拷贝个数)数组拷贝

5. BigDecimal类

用于解决浮点型运算精度丢失问题。


**使用方式:**创建BigDecimal对象封装浮点类型数据 (通过valueOf方法创建)

public static BigDecimal valueOf(double val) 

BigDecimal类常用API:

方法名说明
public BigDecimal add(BigDecimal b)加法
public BigDecimal subract(BigDecimal b)减法
public BigDecimal multiply(BigDecimal b)乘法
public BigDecimal divide(BigDecimal b)除法

6. 日期与时间

6.1 Date

  • Date类的对象可以获取系统当前的日期时间。

  • 它在java.util包下。

1、Date类的构造器:

// 创建一个Date对象,代表的是系统当前的日期时间(精确到毫秒)
public Date() 

2、Date类常用方法:

// 获取时间对象的毫秒值
public long getTime()

3、时间毫秒值->日期对象:

// 有参构造器
public Date(long time) // 把时间毫秒值转换成Date日期对象
// 设置日期对象的时间,参数为时间毫秒值
public void setTime(long time)

示例:计算当前时间往后走1小时121秒之后的时间是多少?

public class DateTest2 {
    public static void main(String[] args) {
        // 获取当前系统时间的毫秒值
        long time = System.currentTimeMillis();
        System.out.println("当前时间为:");
        System.out.println(new Date(time));
        time += (60 * 60 + 121) * 1000;
        System.out.println("当前时间往后走1小时121秒之后的时间是:");
        System.out.println(new Date(time));
    }
}


6.2 SimpleDateFormat

  • SimpleDateFormat可以把Date对象或毫秒值格式化成我们喜欢的时间形式。
  • 也可以把字符串的时间形式解析成日期对象。
格式化:
		Date对象  ->  2022年6月30日 18:40
        时间毫秒值 ->  2022年6月30日 18:40   
        
解析:	   2022年6月30日 18:40 -> Date对象

1、SimpleDateFormat的构造器:

构造器说明
public SimpleDateFormat()构造一个SimpleDateFormat对象,使用默认格式
public SimpleDateFormat(String pattern)构造一个SimpleDateFormat对象,使用指定的格式

2、SimpleDateFormat的格式化方法:

构造器说明
public final String format(Date date)将日期对象格式化成日期/时间字符串
public final String format(Object time)将时间毫秒值格式化成日期/时间字符串
  • 被final修饰的方法不能被重写。

格式化的时间格式:

: y
月: M: d
时: H: m
秒: s
    
完整格式:yyyy-MM-dd HH:mm:ss (2022-6-30 19:04:30)  

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CKJHXsxo-1656678744859)(常用的API.assets/image-20220630190809853.png)]

3、SimpleDateFormat解析字符串时间并返回日期对象:

解析方法说明
public Date parse(String source)从给定字符串的开始解析文本来生成日期

示例:计算出2022年06月30日 19点06分55秒,往后走2天14小时49分06秒后的时间是多少。

public class SimpleDateFormatTest2 {
    public static void main(String[] args) throws ParseException {
        // 1、定义字符串时间
        String dateStr = "2022年06月30日 19点06分55秒";

        // 2、将字符串时间解析成日期对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH点mm分ss秒");
        Date date = sdf.parse(dateStr);

        // 3、将时间毫秒值往后走2天14小时49分06秒
        long time = date.getTime() + (24 * 60 * 60 * 2L + 14 * 60 * 60 + 49 * 60 + 6) * 1000;
        
        // 4、格式化结果
        dateStr = sdf.format(time);
        System.out.println(dateStr); // 2022年07月03日 09点56分01秒
    }
}

6.3 Calendar

  • Calendar代表系统此刻日期对应的日历对象。
  • Calendar是一个抽象类,不能直接创建对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n3R8gdZV-1656678744860)(常用的API.assets/image-20220630193701451.png)]

// 通过方法获取实例(多态)
public static Calendar getlnstance()

常用方法:

方法名说明
public int get(int field)获取日期中的某个字段信息
public void set(int field, int value)修改日历的某个字段
public void add(int field, int amount)为某个字段添加/减少指定的值
public final Date getTime()拿到此刻日期对象
public long getTimeInMillis()拿到此刻时间毫秒值

注意:Calendar是可变日期对象,一旦修改后会其对象本身表示的时间会发生变化。


实例:Calendar的使用

// 获取的操作用的多
public class CalendarTest {
    public static void main(String[] args) {
        // 1、拿到系统此刻的日历对象
        Calendar cal = Calendar.getInstance();
        //System.out.println(cal);
        /*
            字段对应的数据:
            java.util.GregorianCalendar[
                time=1656591237954,
                areFieldsSet=true,
                areAllFieldsSet=true,
                lenient=true,
                zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],
                firstDayOfWeek=1,
                minimalDaysInFirstWeek=1,
                ERA=1,
                YEAR=2022,
                MONTH=5,
                WEEK_OF_YEAR=27,
                WEEK_OF_MONTH=5,
                DAY_OF_MONTH=30,
                DAY_OF_YEAR=181,
                DAY_OF_WEEK=5,
                DAY_OF_WEEK_IN_MONTH=5,
                AM_PM=1,HOUR=8,
                HOUR_OF_DAY=20,
                MINUTE=13,
                SECOND=57,
                MILLISECOND=954,
                ZONE_OFFSET=28800000,
                DST_OFFSET=0]
         */

        // 2、获取日历的信息
        int year = cal.get(Calendar.YEAR);
        System.out.println("year = " + year);
        int month = cal.get(Calendar.MONTH + 1);
        System.out.println("month = " + month);// 它从0开始
        int days = cal.get(Calendar.DAY_OF_YEAR);
        System.out.println("今年已将过去" + days+"天"); //今年已将过去181天

        // 3、public void set(int field, int value):修改日历某个字段信息,通常不修改
        // 修改年
        // cal.set(Calendar.YEAR,2023);
        // System.out.println("修改之后的年份为:"+cal.get(Calendar.YEAR));

        // 4、public void add(int field, int amount):为某个字段添加/减少指定的值
        // 64天后是什么时间
        cal.add(Calendar.DAY_OF_YEAR,64);


        // 5、public final Date getTime():拿到此刻日期对象,不常用
        Date date = cal.getTime();
        System.out.println("date="+date);//date=Fri Sep 02 20:29:53 CST 2022

        // 6、public long getTimeInMillis():拿到此刻时间毫秒值,不常用
        System.out.println(cal.getTimeInMillis()); //1662121793001
    }
}

7. JDK8 新增的日期类

7.1 LocalDate、LocalTime、LocalDateTime

  • LocalDate、LocalTime、LocalDateTime:他们分别表示日期,时间,日期时间对象,他们的类的实例是不可变的对象。
  • 他们三者构建对象和API都是通用的。




7.2 Instant(时间戳)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pfBmiqdd-1656678744860)(常用的API.assets/image-20220701172054491.png)]


7.3 DateTimeFormatter


7.4 Duration、Period


  • Duration: 用于计算两个 “时间” 间隔。

  • Period: 用于计算两个 “日期” 间隔。


7.5 ChronoUnit


8. 包装类

包装类是Java提供的一组类,专门用来创建8种基本数据类型对应的对象,一共8个包装类,存放在 java.lang包。

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

8.1 为什么要有包装类?

  • Java为了万物皆对象,为8种基本类型提供了对应的包装类。
  • 集合和泛型不支持基本数据类型,只能支持包装类型。

包装类体系结构如下:

img

示例:

public class IntegerDemo {
    public static void main(String[] args) {
        // 定义一个字符串
        String str = "123";
        // 将字符串转换成整型
        int num = Integer.parseInt(str);
        System.out.println(num++); // 123
    }
}

8.2 自动装箱和拆箱

  • 装箱:将基本数据类型转为对应的包装类对象,利用各个包装类的构造方法完成。
  • 拆箱:将包装类对象转为对应的基本数据类型,利用Number类的xxxValue()方法完成(xxx表示基本数据类型的名称)。
  • JDK1.5之前,使用手动方式进行装箱和拆箱的操作。
  • JDK1.5之后,使用**自动装箱(Autoboxing)自动拆箱(Auto Unboxing)**的操作。(所以我们使用的便利是拿编译器的辛苦换来的🤭)

示例:

public class TestBoxingAndUnboxing {
    public static void main(String[] args) {
        // 1、基本数据类型变为包装类,装箱
        // 通过传入基本类型数据,然后使用new关键字调用Integer类的构造方法,将其变为Integer类的对象intObj,整个过程为装箱操作。
        Integer intObj = new Integer(10);
        // 2、包装类变为基本类型,拆箱
        // 将包装类Integer类的对象intObj,还原为基本类型,并赋值给整型变量temp,整个过程为拆箱操作。
        int temp = intObj.intValue();
        System.out.println("整型变量temp的值为:" + temp);

        System.out.println("---------------分割线-----------------");

        int temp2 = 345;
        // 3、自动装箱
        //在编译阶段,编译器会自动将 intObj = temp2;  这条语句扩转为:intObj = intObj.valueOf(temp2);
        intObj = temp2;
        // 4、自动拆箱
        //在编译阶段,编译器会自动将  int temp3 = intObj;  这条语句扩转为: int temp3 = intObj.intValue();
        int temp3 = intObj;
        temp3++;
        System.out.println("整型变量temp3的值为:" + temp3);

        // 自动装箱
        Boolean boo = true;
        // 自动拆箱
        boolean flag = boo;
        System.out.println(flag && false);
    }
}

img


8.3 基本类型与字符串的转换

使用包装类的特点是将字符串变为指定的基本类型数据。

  • 以Integer为例: public static int parseInt(String s);
  • 以Double为例: public static int parseDouble(String s);
  • 以Boolean为例: public static int parseBoolean(String s);

但是以上的操作方法形式对于字符类型(character)是不存在的。因为String类有一个charAt()方法,可以取得指定索引的字符。

示例:

public class Test3 {
    public static void main(String[] args) {
        // 定义一个字符串
        String str = "3.14";
        // 将字符串转为double
        double d = Double.parseDouble(str);
        System.out.println("d:" + d);

        //重新给字符串赋值
        str = "true";
        boolean flag = Boolean.parseBoolean(str);
        if (flag){
            System.out.println("条件满足!");
        }else{
            System.out.println("条件不满足!");
        }
    }
}

运行结果如下:
在这里插入图片描述


8.4 将基本类型变为字符串

  • 使用String类中的valueOf()方法。

  • 或者拼接字符串,str+“”。

示例:

public class Test3 {
    public static void main(String[] args) {
     int intValue = 100;
        // 将整型变量转换成字符串型
        String str = String.valueOf(intValue);
        System.out.println(str);

        double e = 2.718;
        // 将double变量转换成字符串型
        str = String.valueOf(e);
        System.out.println(str);
    }
}

运行结果如下:
在这里插入图片描述


8.5 Integer数值比较

public class Test {
    public static void main(String[] args) {
    	// 自动装箱,相当于 Integer.valueOf();
        Integer a = 200;
        Integer b = 200;
        Integer c = 100;
        Integer d = 100;
        int e = 200;
        System.out.println(a == b); // false
        System.out.println(c == d); // true
        // 先自动拆箱相当于Integer.intValue();,然后再判断是否相等
        System.out.println(b == e); // true
    }
}

如果整型字面量的值在-128 到 127 之间,那么不会 new 新的 Integer 对象,而是直接引用常量池
中的 Integer 对象,所以 c = = d 的结果是 true,而 a = = b 的结果是 false。


9. 正则表达式

正则表达式可以用一些规定的字符来制定规则,并用来校验数据格式的合法性。例如:表单验证等等

需求:校验一个QQ号码是否正确,6位或20位号之内必须全部是数字

public class RegexDemo1 {
    public static void main(String[] args) {
        // System.out.println(check1("1234567889"));
        // System.out.println(check1("123456a7889"));

        // 使用正则表达式校验
        System.out.println(check2("1234567889"));
    }

    /**
     * 常规写法
     *
     * @param qq
     * @return
     */
    public static boolean check1(String qq) {
        // 1、判断qq长度是否满足要求
        if (qq == null || qq.length() < 6 || qq.length() > 20) {
            return false;
        }
        //2、使用循环遍历每个字符,然后判断qq中是否全部是数字
        for (int i = 0; i < qq.length(); i++) {
            char ch = qq.charAt(i);
            // 非数字判断
            if (ch < '0' || ch > '9') {
                return false;
            }
        }
        return true;
    }


    /**
     * 使用正则表达式校验
     *
     * @param qq
     * @return
     */
    public static boolean check2(String qq) {
        /*
                \d 表示全部是数字
                \\ 转义字符  ->  \
                {6,20} 表示[6,20]之间的数
         */
        return qq != null && qq.matches("\\d{6,20}");

    }
}

9.1 正则表达式的匹配规则

java.util.regex.Pattern匹配规则类

1、字符类(默认匹配一个字符)

[abc]           只能是a、b或者c    
[^abc]          除了a、b、c之外的任何字符  
[a-zA-Z]        a到z或AZ 之间的字符  
    
[a-d[m-p]]      a到d或m到p:[a-dm-p](并集) 
[a-z&&[def]]    d、e或f(交集) 
[a-z&&[^bc]]    a到z,除了b和c:[ad-z](减法) 
[a-z&&[^m-p]]   a到z,而非m到 p:[a-lq-z](减法)     

2、预定义的字符类(默认匹配一个字符)

.       任何字符(与行结束符可能匹配也可能不匹配) 
\d      一个数字:[0-9] 
\D      非数字: [^0-9] 
\s      一个空白字符:[ \t\n\x0B\f\r] 
\S      非空白字符:[^\s] 
\w      单词字符(英文、数字、下划线)[a-zA-Z_0-9] 
\W      一个非单词字符:[^\w] 

3、贪婪的量词(配合匹配多个字符)

X?          X,一次或一次也没有 
X*          X,零次或多次 
X+          X,一次或多次 
X{n}        X,正好 n 次 
X{n,}       X,至少 n 次 
X{n,m}      X,至少 n 次,但是不超过 m 次 

4、String类的matches()方法可以与正则表达式进行匹配。

// 判断是否匹配正则表达式,匹配返回true,不匹配返回false。
public boolean matches(String regex)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XR2y5AHx-1656678744862)(常用的API.assets/image-20220701090204845.png)]

示例:

System.out.print1n("a".matches("[abc]"));    // true
System.out.println("z".matches("[abc]"));    // false
System.out.print1n("ab".matches( "[abc]")); // falre,只能匹配一个
System.out.print1n("ab".matches("[abc ]+")); // true

9.2 正则表达式的常见案例

1、请编写程序模拟用户输入手机号码、验证格式正确,并给出提示,直到格式输入正确为止。

public class RegexPhone {
    public static void main(String[] args) {
        check();
    }

    public static void check() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入你注册的手机号码:");
            String phone = sc.next();
            // 判断手机号码格式是否正确,1开头,第二位3-9,之后九位没有要求
            if(phone.matches("1[3-9]\\d{9}")){
                System.out.println("手机号码格式正确,注册完成~");
                break;
            }else {
                System.out.println("格式有误!");

            }
        }
    }
}

2、请编写程序模拟用户输入邮箱号码、验证格式正确,并给出提示,直到格式输入正确为止。

public class RegexEmail {
    public static void main(String[] args) {
        check();
    }

    public static void check() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入你注册的邮箱:");
            String email = sc.next();
            /*
                1433123335@qq.com
                \\w{1,30} 用户名
                @[a-zA-Z0-9]{2,20} @xxx
                \\.  ->   .
                ([a-zA-Z]{2,20}){1,2} 有可能一级域名或者两级域名

             */
            if(email.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z]{2,20}){1,2}")){
                System.out.println("邮箱格式正确,注册完成~");
                break;
            }else {
                System.out.println("格式有误!");

            }
        }
    }
}

3、请编写程序模拟用户输入电话号码、验证格式正确,并给出提示,直到格式输入正确为止。

public class RegexPhone {
    public static void main(String[] args) {
        check();
    }

    public static void check() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入你的电话号码:");
            String phone = sc.next();
           
            if(phone.matches("0\\d{2,6}-?\\d{5,20}")){
                System.out.println("格式正确,注册完成~");
                break;
            }else {
                System.out.println("格式有误!");

            }
        }
    }
}

9.3 正则表达式在方法中的应用

正则表达式在字符串方法中的使用:

方法名说明
public String replaceAll(String regex,String newStr)按照正则表达式匹配的内容进行替换
public String sptit(String regex)按照正则表达式匹配的内容进行分割字符串,并返回一个字符串数组。

9.4 正则表达式爬取信息

/**
 * 需求:从下面信息解析电话号和邮箱
 *
 * @author 白豆五
 * @version 2022/7/1 14:25
 * @since JDK8
 */
public class RegexContent {
    public static void main(String[] args) {
        // 1、编写字符串数据
        String rs = "来黑马程序学习Java,电话020-43422424,或者联系邮箱" +
                "itcast@itcast.cn,电话18762832633,0203232323" +
                "邮箱bozai@itcast.cn,400-100-3233 , 4001003232";

        // 2、定义爬取规则
        /*
            邮箱:   \w{1,}@\w{2,10}(\.\w{2,10}){1,2}
            手机号: 1[3-9]\d{9}
            电话号: 1[3-9]\d{9} , 400-?\d{3,8}-?\d{3,8}
         */
        String regex = "(\\w{1,}@\\w{2,10}(\\.\\w{2,10}){1,2})|" +
                "(1[3-9]\\d{9})|(0\\d{2,5}-?\\d{5,15})|(400-?\\d{3,8}-?\\d{3,8})";


        // 3、编译正则表达式后返回一个匹配规则对象
        Pattern pattern = Pattern.compile(regex);

        // 4、获取匹配器对象
        Matcher matcher = pattern.matcher(rs);

        // 5、通过匹配器去内容中爬取信息
        while (matcher.find()){
            System.out.println(matcher.group());
        }
    }
}

10. Arrays类

java.util. Arrays数组操作工具类,专门用于操作数组元素。

Arrays类常用API:

方法名说明
public static String toString(数据类型[] a)返回数组中的内容
public static void sort(数据类型[] a)对数据进行排序(默认升序)
public static void sort(数据类型[] a, Comparator<? super T> c)使用比较器对熊自定义排序
public static int binarySearch(int[]a, int key)二分搜索数组中的数据,存在返回索引,不存在返回-1

拷贝数组:System.arraycopy()比Arrays.copyOf()更高效。

11. 常见算法

11.1 选择排序

思想:每轮选择当前的位置,开始找出后面较小值与该位置交换。

选择排序的关键步骤:

  • 确定总共需要选择几轮:数组的长度-1。
  • 控制每轮以当前位置为基础,与后面元素进行比较。
public class SelectionSort {
    public static void main(String[] args) {
        // 1、定义数组
        int[] arr = {5, 1, 3, 2};
        // 2、定义一个循环,控制选择几轮 arr.length - 1
        for (int i = 0; i < arr.length - 1; i++) {
            // 定义内部循环,控制内部选择几次
            for (int j = i + 1; j < arr.length; j++) {
                // 当前位 arr[i]
                // 如果后面的数据比当前位的数据还小,则交换
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

    }
}

11.2 二分查找

  • 基本查找:从前往后逐个比较元素,效率低。

  • 二分查也叫对半查找,它的性能更好,二分查找的前提是数组必须是排好序的。

  • 二分查询相当于每次去掉一半的查找范围。

实现步骤:

1、定义变量记录左边和右边的位置。

2、使用while循环控制查找(条件左边位置<=右边位置)。

3、循环内部获取中间元素索引。

4、判断当前要找的元素如果大于中间元素,左边位置=中间索引+1。

5、判断当前要找的元素如果小于中间元素,右边位置=中间索引-1。

6、判断当前要找的元素如果等于中间元素,返回当前中间元素索引。

public class BinarySearch {
    public static void main(String[] args) {

        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println(binarySearch(arr,30));
    }

    /**
     * 二分查找算法的实现
     *
     * @param arr  排序的数组
     * @param data 要找的数据
     * @return 索引,如果元素不存在返回-1
     */
    public static int binarySearch(int[] arr, int data) {
        // 1、定义左边位置和右边位置
        int left = 0;
        int right = arr.length - 1;
        //  2、循环折半查询
        while (left <= right) {
            // 取中间索引
            int middleIndex = (left + right) / 2;
            // 3、判断data是否大于中间元素
            if (data > arr[middleIndex]) {
                //往右边找
                left = middleIndex + 1;
            }else if(data<arr[middleIndex]){
                //往左边找
                right=middleIndex-1;
            }else {
                return middleIndex;
            }
        }
        return -1;
    }
}

12. Lambda表达式

Java8是Java语言自JDK1.5以后的一个重大的里程碑版本,因为它增加了很多新特性,这些新特性会改变编程的风格和解决问题的方式。

例如:日期时间API、Lambda表达式、Stream API(操作集合)、方法引用、CompletableFuture(异步编程)等。

Lambda表达式的作用:简化匿名内部类的写法。

12.1 函数式编程思想

之前我们写的代码都是面向对象的编程思想,该思想强调的是通过对象来做事情。例如 我们想要线程执行任务就必须创建一个实现Runnable接口的实现类对象,但是我们真正要做的事情实际上就是执行run方法中的代码从而来执行线程的任务。

函数式编程思想省略了创建对象的复杂语法,然后通过 lambda表达式 直接传递代码来执行线程任务。而不需要创建 Runnable接口的实现类对象。

函数式编程思想强调的是做什么,而不是以什么方式去做。

面向对象编程和函数式编程两种编程风格的对比:(函数式编程相比oop语法更加整洁)

package com.baidou.java.jdk.feature.java8;

/**
 * Lambda表达式的使用
 *
 * @author baidou 1433021114@qq.com
 * @version 2022/6/5 14:14
 * @since JDK8
 */
public class LambdaExpressionTest {
    public static void main(String[] args) {
        new LambdaExpressionTest().testLambdaExpression();
    }


    /**
     * 面向对象编程和函数式编程两种编程风格的对比
     */
    public void testLambdaExpression() {
        // 面向对象的方式创建和启动线程
        new Thread(new CustomRunnable()).start();

        // 函数式编程方式创建和启动线程
        new Thread(()->{
            System.out.println("2.函数式编程方式创建和启动线程");
        }).start();
    }

}

/**
 * 定义一个类实现Runnable接口
 */
class CustomRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("1.面向对象的方式创建和启动线程");
    }
}

12.2 函数式接口

函数式接口表示接口中只有一个抽象方法,而且用注解@FunctionalInterface标记的接口就是函数式接口。

这里需要注意的是,接口中如果有其他的方法(默认方法、静态方法),但是只有一个抽象方法,它也是函数式接口,例如java.util.Comparator接口。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

自定义函数式接口:

package com.baidou.java.jdk.feature.java8;

/**
 * 自定义函数式接口
 *
 * @author baidou 1433021114@qq.com
 * @version 2022/6/5 14:56
 * @since JDK8
 */
@FunctionalInterface
public interface CustomFunctionalInterface {
    // 实现两个整数相加
    int add(int a, int b);
}

12.3 Lambda表达式的使用

要想使用Lambda表达式必需先有函数式接口,Lambda表达式也是函数式编程思想的体现。

Lambda表达式的语法格式

1、Lambda表达式的标准语法格式

()->{}    

解释: () 表示重写函数式接口的抽象方法的参数列表
     -> 表示lambda表达式的固定组成部分,箭头表示它指向什么
     {} 表示重写函数式接口的抽象方法的方法体,也是方法要做的事情
/**
 * lambda表达式的完整格式使用
 */
@Test
public void testColloectionsSort() {
    List<Integer> list = new ArrayList<>();
    list.add(77);
    list.add(66);
    list.add(11);
    list.add(22);
    list.add(55);
    list.add(1024);
    // 使用匿名内部类降序排序
    Collections.sort(list, new Comparator<Integer>() {
        @Override
        public int compare(Integer value1, Integer value2) {
            return value2 - value1;
        }

    });
    System.out.println("使用匿名内部类降序排序list集合的结果是" + list);

    // 使用lambda表达式降序排序
    Collections.sort(list, (Integer value1, Integer value2) -> {
        return value2 - value1;
    });
    System.out.println("使用lambda表达式降序排序list集合的结果是" + list);
}

2、Lambda表达式的简化语法格式

简化之前:

// 使用lambda表达式降序排序
Collections.sort(list, (Integer value1, Integer value2) -> {
    return value2 - value1;
});
  • 参数的数据类型可以不写;
  • {}中如果只有一条执行语句,{}; 以及 return 都可以不写。(三个必须一起省略)

简化之后:

Collections.sort(list, (value1,value2) -> value2 - value1);

Lambda表达式的应用场景

1、变量(使用极少)

package com.baidou.java.jdk.feature.java8;

/**
 * 自定义函数式接口
 *
 * @author baidou 1433021114@qq.com
 * @version 2022/6/5 14:56
 * @since JDK8
 */
@FunctionalInterface
public interface CustomFunctionalInterface {
    // 实现两个整数相加
    int add(int a, int b);
}
/**
 * lambda表达式的应用场景
 */
@Test
public void testLambdaExpressionUsage() {
    // 将lambda表达式赋值给一个变量
    CustomFunctionalInterface c = (int a, int b) -> {
        return a + b;
    };
    int result = c.add(12, 34);
    System.out.println("result = " + result);
}

2、方法的参数

Collections.sort(list, (value1,value2) -> value2 - value1);

3、方法的返回值

/**
 * lambda表达式可以作为方法的返回值
 */
public CustomFunctionalInterface getCustomFunctionalInterface(){
    return (int a,int b)->{return a+b;};
}
CustomFunctionalInterface c = getCustomFunctionalInterface();
System.out.println("result = " + c.add(11, 22));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白豆五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值