• 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));
    }
    
    • 1
    • 2
    • 3

    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) 
    
    • 1

    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() 
    
    • 1
    • 2

    2、Date类常用方法:

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

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

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

    示例:计算当前时间往后走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));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11


    6.2 SimpleDateFormat

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

    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)  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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秒
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    6.3 Calendar

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

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

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

    常用方法:

    方法名说明
    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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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("条件不满足!");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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


    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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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


    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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果整型字面量的值在-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}");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    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](减法)     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

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

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

    X?          X,一次或一次也没有 
    X*          X,零次或多次 
    X+          X,一次或多次 
    X{n}        X,正好 n 次 
    X{n,}       X,至少 n 次 
    X{n,m}      X,至少 n 次,但是不超过 m 次 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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
    
    • 1
    • 2
    • 3
    • 4

    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("格式有误!");
    
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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("格式有误!");
    
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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("格式有误!");
    
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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());
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    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));
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    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.面向对象的方式创建和启动线程");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    12.2 函数式接口

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

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

    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }
    
    • 1
    • 2
    • 3
    • 4

    自定义函数式接口:

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    12.3 Lambda表达式的使用

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

    Lambda表达式的语法格式

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

    ()->{}    
    
    解释: () 表示重写函数式接口的抽象方法的参数列表
         -> 表示lambda表达式的固定组成部分,箭头表示它指向什么
         {} 表示重写函数式接口的抽象方法的方法体,也是方法要做的事情
    
    • 1
    • 2
    • 3
    • 4
    • 5
    /**
     * 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

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

    简化之前:

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

    简化之后:

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

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    /**
     * 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、方法的参数

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

    3、方法的返回值

    /**
     * lambda表达式可以作为方法的返回值
     */
    public CustomFunctionalInterface getCustomFunctionalInterface(){
        return (int a,int b)->{return a+b;};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    CustomFunctionalInterface c = getCustomFunctionalInterface();
    System.out.println("result = " + c.add(11, 22));
    
    • 1
    • 2
  • 相关阅读:
    不知道10年老电脑如何重装系统?其实很简单
    cemtos 超详细安装JDK并配置系统参数环境
    Java数据结构 | 模拟实现优先级队列
    为什么su模型导入3D有黑点?原因分析与解决方案---模大狮模型网
    如何高效解决工作上的问题?一站式工单系统有什么用?
    [SpringMVC笔记] SpringMVC-12-放行静态资源访问
    链式二叉树高质量OJ—【Leedcode】
    《MongoDB入门教程》第11篇 数组运算符
    Linux sed命令增删改查 附代码
    Web3 世界的名片
  • 原文地址:https://blog.csdn.net/qq_46921028/article/details/125565331