JAVA抽象类,接口与内部类,常用API知识总结

news2024/11/24 6:04:53

文章目录

  • 抽象类和抽象方法
    • 抽象类的定义格式
    • 抽象方法的定义格式
    • 注意事项
  • 接口
    • 定义和使用
    • 成员特点
    • 和类之间的关系
    • 新增
      • JDK8新增方法
      • JDK9新增方法
    • 总结
    • 设计模式
  • 内部类
    • 使用场景
    • 分类
    • 成员内部类
      • 获取内部类对象
      • 访问成员变量
    • 静态内部类
    • 局部内部类
    • 匿名内部类
      • 格式
      • 使用场景
    • 示例
  • 常用API
    • Math
    • System
    • Runtime
    • Object
    • Objects
    • BigInteger
    • BIgDecimal
    • 正则表达式
      • 爬虫
      • 字符串方法
      • 捕获分组
      • 非捕获分组
    • JDK7时间
      • Date时间类
      • Calendar
      • SimpleDateFormat 类

抽象类和抽象方法

**抽象方法:**将共性的行为(方法)抽取到父类之后,由于每一个子类执行的内容是不一样,所以,在父类中
不能确定具体的方法体。该方法就可以定义为抽象方法。

**抽象类:**如果一个类中存在抽象方法,那么该类就必须声明为抽象类

意义:强制子类按照固定格式编写,增强了代码的规范性。

抽象类的定义格式

public abstract 返回值类型 方法名(参数列表);

抽象方法的定义格式

public abstract class 类名{}

注意事项

  1. 抽象类不能实例化:抽象类是为了被子类继承而设计的,因此不能被直接实例化。抽象类的主要目的是作为其他类的基类,用于被继承,而不是被实例化。如果尝试实例化一个抽象类,编译器会报错。
  2. 抽象类中不一定有抽象方法:抽象类中可以包含普通方法、静态方法、成员变量等,不一定要有抽象方法。但是,如果一个类中有抽象方法,那么这个类必须是抽象类。
  3. 抽象类可以有构造方法:抽象类可以包含构造方法,用于初始化抽象类的成员变量等。子类在实例化时会调用抽象类的构造方法,可以通过super关键字来调用。
  4. 抽象类的子类:子类要么重写抽象类中的所有抽象方法,要么自己也是抽象类。一般使用前者。如果一个子类没有实现父类的所有抽象方法,那么这个子类必须声明为抽象类。

继承抽象类的子类如何重写抽象方法:

// Animal.java
public abstract class Animal {
    private String name;
    private int age;

    public abstract void eat();

    public void drink() {
        System.out.println("喝水");
    }


    public Animal() {

    }
// 这里省略setter和gertter
}

// Frog.java
public class Frog extends Animal{
    public Frog() {
    }

    public Frog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("吃虫子");
    }
}

接口

接口是一种规则,是对行为的抽象

定义和使用

  • 接口用关键字interface来定义
[可见度] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}
/* 文件名 : Animal.java */
public abstract interface Animal {
   public abstract void eat();
   public abstract void travel();
}
  • 接口不能实例化

  • 接口和类之间是实现关系,通过implements关键字表示

    public class 类名 implements 接口名{}
    
  • 接口的子类(实现类)
    要么重写接口中的所有抽象方法
    要么是抽象类

  • 注意1:接口和类的实现关系,可以单实现,也可以多实现。

    public class 类名 implements 接口名1,接口名2 {}
    
  • 注意2:实现类还可以在继承一个类的同时实现多个接口。

    public class 类名 extends 父类 implements 接口名1,接口名2 {}
    

成员特点

  • 成员变量

    只能是常量,默认修饰符为 public static final

    公共的、静态的(不与任何实例对象相关联)、且只能赋值一次的常量。在接口中声明变量时,可以直接初始化,但不可以在接口中使用实例初始化块进行初始化。

  • 构造方法

    **接口不包含构造方法。**因为接口主要是用于描述行为,而不是描述对象的状态,所以没有构造方法的需求。

  • 成员方法

    只能是抽象方法,默认修饰符为public abstract

和类之间的关系

  • 类和类的关系

继承关系,只能单继承,不能多继承,但是可以多层继承

  • 类和接口的关系

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

一个类实现了多个接口,并且这些接口中存在同名方法时,实现类并不需要显式地重写这个方法,只需要提供一次具体的实现即可。

  • 接口和接口的关系

继承关系,可以单继承,也可以多继承

实现类实现最下面的子接口要重写所有抽象方法

新增

  • JDK7以前:接口中只能定义抽象方法

  • JDK8的新特性:接口中可以定义有方法体的方法。(默认、静态)

  • JDK9的新特性:接口中可以定义私有方法


JDK8新增方法

  • 允许在接口中定义默认方法,需要使用关键字 default 修饰
    作用:解决接口升级的问题

  • 接口中默认方法的定义格式:
    格式:public default 返回值类型 方法名(参数列表){}
    范例:public default void show(){}

  • 接口中默认方法的注意事项

    1. 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
    2. public可以省略,default不能省略
    3. 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
  • 允许在接口中定义静态方法,需要用 static 修饰

  • 接口中静态方法的定义格式:
    格式:public static 返回值类型 方法名(参数列表){}
    范例:public static void show(){}

  • 接口中静态方法的注意事项:
    静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
    public可以省略,static不能省略

正常强制重写,默认不强制重写,静态强制不能重写

JDK9新增方法

  • 允许在接口中定义私有方法,需要用 private 修饰

    不让外界访问,给本接口默认方法或静态方法服务

  • 接口中静态方法的定义格式:

    格式:private 返回值类型 方法名(参数列表){}(默认方法)
    范例:private void show(){}

    格式:private static 返回值类型 方法名(参数列表){}(静态方法)
    范例:private static void method(){}

总结

接口与类之间的关系更多地是一种协议或契约,类通过实现接口来说明自己能够执行某些操作或具备某些行为。

  1. 接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了,
  2. 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态,

设计模式

设计模式是一套被反复使用、多数人知晓、经过分类编目的、代码设计经验的总结。设计模式的本质是解决问题的方案,是一种在特定场景下解决特定问题的经验总结。设计模式提供了一种标准的解决方案,可以帮助开发人员解决常见的设计问题,提高代码的可读性、可维护性和可扩展性。

适配器设计模式:

当一个接口中的抽象方法过多,但我只需要使用其中一部分,就可以使用适配器设计模式

步骤:

  1. 编写中间类xxxAdapter实现对应接口
  2. 对接口中的抽象方法进行空实现
  3. 让真正的实现类继承中间类,并重写需要用的方法
  4. 为了避免其他类创建适配器类的对象,中间的适配器类使用abstract修饰

内部类

内部类是定义在另一个类内部的类。

  • 内部类可以访问外部类的成员,包括私有成员

  • 外部类访问内部类的成员,必须创建对象

使用场景

B类表示的事物是A类的一部分,且B单独存在没有意义

分类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

成员内部类

写在成员位置的,属于外部类的成员。

  • 成员内部类可以被一些修饰符所修饰,比如:private,默认,protectedpublicstatic
  • 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。

获取内部类对象

  1. 当成员内部类被**private**修饰时
    在外部类编写方法,对外提供内部类对象
  2. 当成员内部类被非私有修饰时,直接创建对象,
    Outer.inner oi= new Outer().new inner()
  • 当成员内部类被非私有修饰时,直接创建对象,
// 当成员内部类被非私有修饰时,直接创建对象,
public class Outer {
    String name;
    int age;

    public class Inner {
        String finger;
        int count;
    }
}

public class Test {
    public static void main(String[] args) {
        Outer i = new Outer();
        System.out.println(i.name);
        System.out.println(i.age);

        Outer.Inner j = new Outer().new Inner();// 创建内部类的对象 j
        System.out.println(j.finger);
        System.out.println(j.count);
    }
}
  • 当内部类使用private修饰,无法直接访问内部类成员,可以让外部类提供方法返回内部类对象

    // 内部类使用private修饰
    public class Outer {
        String name;
        int age;
    
        private class Inner {
            String finger;
            int count;
        }
    
        public Inner getInstance(){
            return new Inner();
        }
    }
    

访问成员变量

堆内存中存储内部类对象的同时,还会存储一个指向外部类对象的引用(地址)

public class Outer {
    private int a = 10;

    class Inner {
        private int a = 20;

        public void show() {
            int a = 30;
            //堆内存存储内部类中,还存了Outer this,指向外部类对象
            System.out.println(Outer.this.a); // 10
            System.out.println(this.a); // 20
            System.out.println(a); // 30
        }
    }

}
public class Test {
    public static void main(String[] args) {
        Outer.Inner i = new Outer().new Inner();
        i.show();
    }
}

静态内部类

静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。

创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

例:Outer.Inner oi = new Outer.Inner();

调用非静态方法的格式:先创建对象,用对象调用
调用静态方法的格式:外部类名.内部类名.方法名();

例:Outer.Inner.show2();

//静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。
public class Outer {
    int a = 10;
    static int b = 20;

    static class Inner {
        public void show1() {
            Outer oi = new Outer(); // 创建外部类对象
            System.out.println(oi.a); // 访问外部类的非静态成员变量 a
            System.out.println(b); // 访问外部类的静态成员变量 b
        }

        public static void show2() {
            Outer oi = new Outer();
            System.out.println(oi.a);
            System.out.println(b);
        }
    }
}

局部内部类

将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。

  1. 外界无法直接使用: 外界无法直接访问局部内部类,因为它的作用域被限制在方法内部。如果需要使用局部内部类,必须在方法内部先创建该类的对象,然后通过对象来访问其方法和成员变量。
  2. 可以直接访问外部类的成员: 局部内部类可以直接访问外部类的成员,包括成员变量和成员方法。这是因为局部内部类相当于外部类的成员,具有访问外部类成员的权限。
  3. 可以访问方法内的局部变量: 局部内部类可以访问所在方法内的局部变量

声明局部类时不能有访问说明符(即publicprivate)。局部类的作用域被限定在声明这个局部类的块中。

public class Outer {
    private int outerVariable = 10;

    public void method() {
        int methodVariable = 20; // 方法内的局部变量

        class LocalInner {
            public void print() {
                System.out.println(outerVariable); // 访问外部类的成员变量
                System.out.println(methodVariable); // 访问方法内的局部变量
            }
        }

        LocalInner localInner = new LocalInner(); // 创建局部内部类的对象
        localInner.print(); // 调用局部内部类的方法
    }
}

匿名内部类

没有显式的类名,直接在创建对象时定义类的实现

前提:需要一个类或接口作为基础。

如果是实现接口,那么匿名内部类会实现该接口的方法;

如果是继承类,那么匿名内部类会重写该类的方法。

可以写在成员位置,也可以写在局部位置

格式

new 类名或接口名() {
重写方法;
}

使用场景

当方法的参数是接口或者类时
以接口为例,可以传递这个接口的实现类对象
如果实现类只要使用一次,就可以用匿名内部类简化代码

示例

类:

public abstract class Animal {
    public abstract void eat();
}

// Test.java
public class Test {
    public static void main(String[] args) {
        //形式1
        new Animal() {
            @Override
            public void eat() {
                System.out.println("狗吃骨头");
            }
        }.eat();

        //形式2
        Animal dog = new Animal() {
            @Override
            public void eat() {
                System.out.println("狗吃骨头");
            }
        };
        dog.eat();
    }
}

接口:

public interface Inter {
    public abstract void method();
}
// Demo.java
public class Demo {
    public static void main(String[] args) {
        //形式1
        new Inter() {
            @Override
            public void method() {
                System.out.println("重写后方法");
            }
        }.method();

        //形式2:将匿名内部类的实例作为参数传递给另一个方法。
        function(new Inter() {
            @Override
            public void method() {
                System.out.println("重写后方法");
            }
        });
    }

    public static void function(Inter i) {
        i.method();
        //按照以往需要写接口的实现类,并创建对象传递给该方法
    }
}

常用API

Math

私有化构造方法,所以方法都是静态的

常用方法:

方法名说明
public static int abs(int a)获取参数绝对值
public static double ceil(double a)向上取整
public static double floor(double a)向下取整
public static int round(float a)四舍五入
public static int max(int a,int b)取较大值
public static double pow(double a,double b)返回a的b次幂的值
public static double random()返回值为double的随机值,范围**[0.0,1.0)**
public static double sqrt(double a)返回a的平方根
public static double cbrt(double a)返回a的立方根
public class Demo {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++)
            System.out.println(Math.floor(Math.random() * 100 + 1));// 1 到 100 之间随机数
    }
}

System

方法名说明
public static void exit(int status)终止当前运行的 Java 虚拟机
public static long currentTimeMillis()返回当前系统的时间毫秒值形式
public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数)数组拷贝

public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数)

  • 数据源数组:表示要复制的数组。
  • 起始索引:表示从数据源数组的哪个位置开始复制。
  • 目的地数组:表示要将元素复制到的数组。
  • 起始索引:表示从目的地数组的哪个位置开始存放。
  • 拷贝个数:表示要复制的元素个数。

ex:System.arraycopy(arr1, 0, arr2, 0, 10);

  1. 如果数据源数组和目的地数组都是基本数据类型,那么两者的类型必须保持一致,否则会报错
  2. 在拷贝的时候需要考虑数组的长度,如果超出范围也会报错
  3. 如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型

Runtime

Runtime表示当前虚拟机的运行环境

方法名说明
public static Runtime getRuntime()当前系统的运行环境对象
public void exit(int status)停止虚拟机
public int availableProcessors()获得CPU的线程数
public long maxMemory()JVM能从系统中获取总内存大小(单位byte)
public long totalMemory()JVM已经从系统中获取总内存大小(单位byte)
public long freeMemory()JVM剩余内存大小(单位byte)
public process exec(String command)运行cmd命令

Runtime类构造方法是private Runtime() {}

runtime

Runtime 类的构造方法是私有的,因此无法直接通过 new 关键字来创建 Runtime 类的对象。但是 Runtime 类提供了一个静态方法 getRuntime() 来获取当前应用程序的 Runtime 对象,因此可以通过调用这个静态方法来获取 Runtime 对象。

// 方式一
Runtime runtime = Runtime.getRuntime();
System.out.println(runtime.availableProcessors());
// 方式二
System.out.println(Runtime.getRuntime().availableProcessors());

Object

  • Object是Java中的顶级父类。所有的类都直接或间接的继承于Object类。
  • Object类中的方法可以被所有子类访问

构造方法:

public Object()只有空参构造

方法名说明
public string tostring()返回对象的字符串表示形式
public boolean equals(object obj)比较两个对象是否相等
protected object clone(int a)对象克隆

tostring:

Student stu= new student();
String str2 = stu.tostring();
System.out.println(str2); // com.itheima.a04objectdemo.student@4eec7777
System.out.println(stu); // com.itheima.a04objectdemo.student@4eec7777

toString() 方法返回的是包含类名和对象的哈希码的字符串表示形式,格式为 类名@哈希码
system:类名
out:静态变量
system.out:获取打印的对象
println():方法
参数:表示打印的内容
逻辑:打印一个对象的时,底层会调用对象的tostring方法,把对象变成字符串。然后再打印在控制台上,打印完毕换行处理。

可以通过重写类中toString() 方法输出对象的自定义字符串表示形式,而不是默认的地址值。

equals:

equals() 方法是用于比较两个对象是否相等的方法。在 Object 类中,equals() 方法默认实现是比较两个对象的地址值(即引用是否指向同一个对象),因为在 Object 类中,equals() 方法没有被重写。

如果需要在自定义类中实现对象相等的比较,通常需要重写 equals() 方法,以便根据对象的属性值来判断对象是否相等。

equals
public class Person {
    private String name;
    private int age;
    
    // 构造方法、getter 和 setter 方法省略
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true; // 如果是同一个对象,则相等
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false; // 如果传入的对象为空或者不是同一个类的实例,则不相等
        }
        Person person = (Person) obj; // 强制转换为 Person 类型
        return age == person.age && Objects.equals(name, person.name); // 比较姓名和年龄是否相等
    }
}

clone:

  1. 浅克隆:在浅克隆中,只复制对象本身以及对象中的基本数据类型字段的值。对于对象中的引用类型字段,仅复制引用而不复制引用指向的对象。因此,原始对象和克隆对象共享相同的引用对象。如果引用对象被修改,那么原始对象和克隆对象都会受到影响。
  2. 深克隆:在深克隆中,不仅复制对象本身,还会递归地复制对象中所有引用类型字段所引用的对象,直到所有引用的对象都被复制(字符串不是new的会复用串池中的)。这样,原始对象和克隆对象拥有各自独立的引用对象,它们之间互不影响。

默认浅克隆,需要深克隆需要重写方法或者使用第三方工具类

Objects

工具类,提供了一些方法去完成一些功能

方法名说明
public static boolean equals(object a, object b)先做非空判断,比较两个对象
public static boolean isNull(object obj)判断对象是否为Null,为Null返回true,反之
public static boolean nonNull(object obj)判断对象是否为Null,跟isNull的结果相反

BigInteger

方法名说明
public BigInteger(int num,Random rnd)获取随机大整数,范围:[0~2的num次方-1]
public BigInteger(string val)获取指定的大整数
public BigInteger(String val,int radix)获取指定进制的大整数
public static BigInteger valueof(long val)静态方法获取BigInteger的对象,内部有优化
//1
	Random rd = new Random();
	for (int i = 0; i < 20; i++) {
     	BigInteger bd1 = new BigInteger(5, rd);
         System.out.println(bd1);
     }
	
//2
	BigInteger bd2 = new BigInteger("9876543210");//字符串必须整数
	System.out.println(bd2);

//3
	BigInteger bd3 = new BigInteger("1111", 2);
	System.out.println(bd3);

//4 静态方法获取对象,范围较小,long的范围
	BigInteger bd4 = BigInteger.valueOf(2147483647);
	System.out.println(bd4);

valueOf在内部对常用的数字-16 ~ 16进行了优化,提前把-16~16 先创建好BigInteger的对象,如果多次获取不会重新创建新的。

小结:

  1. 如果BigInteger表示的数字没有超出long的范围,可以用静态方法获取,
  2. 如果BigInteger表示的超出long的范围,可以用构造方法获取。
  3. 对象一旦创建,BigInteger内部记录的值不能发生改变。
  4. 只要进行计算都会产生一个新的BigInteger对象
方法名说明
public BigInteger add(BigInteger val)加法
public BigInteger subtract(BigInteger val)减法
public BigInteger multiply(BigInteger val)乘法
public BigInteger divide(BigInteger val)除法,获取商
public BigInteger[] divideAndRemainder(BigInteger val)除法,获取商和余数
public boolean equals(Object x)比较是否相同
public BigInteger pow(int exponent)次幂
public BigInteger max/min(BigInteger val)返回较大值/较小值
public int intValue(BigInteger val)转为int类型整数超出范围数据有误

BIgDecimal

方法名说明
public static BigDecimal valueOf(double val)获取对象
public BigDecimal add(BigDecimal val)加法
public BigDecimal subtract(BigDecimal val)减法
public BigDecimal multiply(BigDecimal val)乘法
public BigDecimal divide(BigDecimal val)除法
public BigDecimal divide(BigDecimal val,精确几位,舍入模式)除法
import java.math.BigDecimal;

public class Demo2 {
    public static void main(String[] args) {
        //1.通过传递double类型的小数来创建对象,不精确
        BigDecimal bd1 = new BigDecimal(0.09);
        BigDecimal bd2 = new BigDecimal(0.01);
        BigDecimal bd3 = bd1.add(bd2);
        System.out.println(bd3);

        //2.通过传递字符串表示的小数来创建对象
        BigDecimal bd4 = new BigDecimal("0.09");
        BigDecimal bd5 = new BigDecimal("0.01");
        BigDecimal bd6 = bd4.add(bd5);
        System.out.println(bd6);//0.10

        //3.通过静态方法获取对象
        BigDecimal bd7 = BigDecimal.valueOf(10);
        BigDecimal bd8 = BigDecimal.valueOf(10);
        System.out.println(bd7 == bd8);//true

        BigDecimal bd9 = BigDecimal.valueOf(10.0);
        BigDecimal bd10 = BigDecimal.valueOf(10.0);
        System.out.println(bd9 == bd10);//false
    }
}
  1. 如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
  2. 如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法
  3. 如果我们传递的是0-10之间的整数,包含0,10,那么方法会返回己经创建好的对象,不会重新new

底层存储:

bigdecimal

转字符,变为ANCII,存数组

负数存符号,正数不存。

正则表达式

方法名说明
public String[] matches(String regex)判断字符串是否满足正则表达式的规则

字符类(只匹配一个字符)

用法注释
[abc]只能是a,b,或c
[^abc]除了a,b,c之外的任何字符
[a-zA-Z]a到z A到Z,包括(范围)
[a-d[m-p]]a到d,或m到p
[a-z&&[def]]a-z和def的交集。为:d,e,f
[a-z&&[ ^bc ]]a-z和非bc的交集。(等同于[ad-z])
[a-z&&[ ^m-p ]a到z和除了m到p的交集。(等同于[a-lq-z])

预定义字符(只匹配一个字符)

.任何字符,\n不匹配
\d一个数字:[0-9]
\D非数字:[ ^0-9]
\s一个空白字符:[\t\n\x0B\f\r]
\S非空白字符:[ ^\s]
\w[a-zA-Z_0-9]英文、数字、下划线
\W[^\w]一个非单词字符
X?X,0次或1次
X*X,0次或多次
X+X,1次或多次
X{n}X,正好n次
X{n,}X,至少n次
X{n,m}X,至少n但不超过m次
(?i)忽略后面字符的大小写
public class Demo3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s1 = sc.next();
        String s2 = sc.next();

        String reges1 = "\\w{4,16}"; //手机号
        String reges2 = "[1-9]\\d{16}(\\d|(?i)x)"; //身份证
        String reges3 = "[1-9]\\d{16}[\\dXx]";

        System.out.println(s1.matches(reges1));
        System.out.println(s2.matches(reges2));
    }
}

爬虫

在一段文本中查找满足要求的内容:

public class Demo4 {
    public static void method1(String str) {
        Pattern p = Pattern.compile("(?i)Java\\s\\d{0,2}");
        //Pattern p = Pattern.compile("((?i)java\\s)(?=1|5|6|7|8)");
        //Pattern p = Pattern.compile("((?i)java\\s)(1|5|6|7|8)");
        //Pattern p =Pattern.compile("((?i)java\\s)(?:1|5|6|7|8)");与上面等价
        Matcher m = p.matcher(str);
        while (m.find()) {
            String s = m.group();
            System.out.println(s);
        }
    }

    public static void main(String[] args) {
        String s = "Java 5(2004年,也称为Java SE 5或Java 1.5):引入了重要的语言增强,如泛型、枚举、自动装箱/拆箱、可变参数和注解等。Java 6(2006年,也称为Java SE 6):加入了JDBC 4.0、Java编译器API、集合框架增强和Web服务支持等功能。Java 7(2011年,也称为Java SE 7):带来了重要的语言和API更新,如try-with-resources语句、switch语句的字符串支持、钻石操作符和Fork/Join框架等。Java 8(2014年,也称为Java SE 8):引入了Lambda表达式、Stream API、新的日期/时间API、默认方法和可重复注解等功能。";
        method1(s);
    }
}

贪婪爬取和非贪婪爬取

贪婪爬取:在爬取数据的时候尽可能的多获取数据
非贪婪爬取:在爬取数据的时候尽可能的少获取数据

ab+:

贪婪爬取:abbbbbbbbbbbb
非贪婪爬取:ab

Java中默认的就是贪婪爬取
在数量词+ *的后面加上问号,此时就是非贪婪爬取

字符串方法

方法名说明
public String[] matches(String regex)判断字符串是否满足正则表达式的规则
public String replaceAll(String regex,String newStr)按照正则表达式的规则进行替换
public String[] split(String regex)按照正则表达式的规则切割字符串

Java中一个方法的形参是正则表达式,则这个方法识别正则表达式

捕获分组

分组就是一个小括号()

每组是有组号的,也就是序号。
规则1:从1开始,连续不间断,
规则2:以左括号为基准,最左边的是第一组,其次为第二组,以此类推

\\组号: 表示把第x组的内容再出来用一次

// 判断一个字符串的开始字符和结束字符是否一致,只考虑一个字符
String regex1 = "(.).+\\1";
// 判断一个字符串的开始部分和结束部分是否一致,可以有多个字符
String regex2 = "(.+).+\\1";
// 判断一个字符串的开始部分和结束部分是否一致,开始部分内部每个字符也需要一致
String regex3 = "((.)\\2*).+\\1";

后续还要继续使用本组的数据:
正则内部使用:\\组号
正则外部使用:$组号

// 表示把重复内容的第一个字符看做一组
// \\1;表示第一字符再次出现
// +;至少一次
// $1:表示把正则表达式中第一组的内容,再拿出来用
    "我要要学学学学编程程程"
    String result= str.replaceAll("(.)\\1+","$1");

非捕获分组

分组之后不需要再用本组数据,仅仅是把数据括起来

符号含义举例
(?: 正则)获取所有`Java(?:8
(?= 正则)获取前面部分`Java(?=81
(?! 正则)获取不是指定内容的前面部分`Java(?!8

JDK7时间

Date时间类

Date类是一个JDK写好的avabean类,用来描述时间,精确到毫秒
利用空参构造创建的对象,默认表示系统当前时间,
利用有参构造创建的对象,表示指定的时间

创建时间对象

Date date = new Date(); //系统当前时间
Date date =new Date(指定毫秒值); //时间原点开始加指定毫秒值后的时间

修改时间对象中的毫秒值:
void setTime(毫秒值);时间原点开始加指定毫秒值后的时间获取时间对象中的毫秒值
long getTime();

Calendar

日历类,抽象类

static Calendar getInstance()

国外月份减1

平闰年判断练习

  public static void method1() {
        Scanner sc = new Scanner(System.in);
        Calendar calendar = Calendar.getInstance();
        int year = sc.nextInt();
        calendar.set(year, 2, 1);
        calendar.add(Calendar.DATE, -1);
        int date = calendar.get(Calendar.DATE);
        if (date == 29) {
            System.out.println("闰年");
        } else {
            System.out.println("平年");
        }
    }

SimpleDateFormat 类

构造方法说明
public simpleDateFormat()构造一个simpleDateFormat,使用默认格式
public SimpleDateFormat(string pattern)构造一个simpleDateFormat,使用指定的格式
常用方法说明
public final string format(Date date)格式化(日期对象->字符串)
public Date parse(string source)解析(字符串 ->日期对象)

simpledateformat

public class test02 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat();
        // 
        Date date1 = new Date();
        String s = sdf.format(date1);
        System.out.println(s);

        Date date2 = sdf.parse("2024/5/11 下午9:58");
        System.out.println(date2);
    }
}
public class test02 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = new Date();
        String s = sdf.format(date1);
        System.out.println(s);

        Date date2 = sdf.parse("2024-05-11 22:04:28");
        System.out.println(date2);
    }
}

sdf.parse只能解析sdf对应的格式
--------: |
| public final string format(Date date) | 格式化(日期对象->字符串) |
| public Date parse(string source) | 解析(字符串 ->日期对象) |

[外链图片转存中…(img-DJ3FrcVV-1715501579117)]

public class test02 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat();
        // 
        Date date1 = new Date();
        String s = sdf.format(date1);
        System.out.println(s);

        Date date2 = sdf.parse("2024/5/11 下午9:58");
        System.out.println(date2);
    }
}
public class test02 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = new Date();
        String s = sdf.format(date1);
        System.out.println(s);

        Date date2 = sdf.parse("2024-05-11 22:04:28");
        System.out.println(date2);
    }
}

sdf.parse只能解析sdf对应的格式



如有错误烦请指正。

感谢您的阅读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1667304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java(三)---逻辑控制

文章目录 前言1.逻辑控制语句的分类1.顺序结构2.分支结构2.1.if结构2.1.1.if...else语句2.2.2.if ... else if... else语句 2.2.switch语句 3.循环结构3.1.while3.2.break3.3.continue3.4.for循环3.5.do while循环 4.输入输出4.1.输入到控制台4.2.从键盘输入 前言 前两篇文章&…

数据分析概念定义和发展前景

数据分析概念定义和发展前景 前言一、数据分析概念二、数据的定义数据的定义数据的分类定性数据定量数据 三、数据的价值数据为什么具有价值 四、数据分析的目的对于企业来说总结 五、数据分析类型的划分描述性统计分析探索性数据分析传统的统计分析方法验证性数据分析 六、 数…

240512-关于如何用VSCode编写C#程序的简单说明

240512-关于如何用VSCode编写C#程序的简单说明 从安装软件开始 &#xff0c;到编写一个HelloWorld的C#文件结束&#xff0c;介绍如何用VSCode编写C#程序 1 上官网下载一个安装包 官网地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/downloads/ 2 打开安装包进…

3D分子生成的定制扩散框架 MolDiff - 评测

MolDiff模型是一种考虑分子键生成的3D分子生成的新模型。MolDiff是清华大学智能产业研究院马剑竹课题组发表在PMLR 2023的工作&#xff0c;第一作者是Xingang Peng&#xff0c;文章题目为&#xff1a;《 Addressing the Atom-Bond Inconsistency Problem in 3D Molecule Genera…

计算机毕业设计 | vue+springboot调查问卷管理系统(附源码)

1&#xff0c;研究目的 在进入21世纪以后&#xff0c;互联网得到了蓬勃的发展&#xff0c;电子问卷调查也开始逐渐流行起来。传统纸质问卷和电子问卷相比较后&#xff0c;传统问卷还存在很多弊端&#xff1a; 问卷分发起来比较困难&#xff0c;并且分发试卷耗费大量的金钱和时…

Vue3项目Easy云盘(二):文件列表+新建目录+文件重命名+文件上传

一、文件列表 1.封装全局组件Table.vue 因为Main.vue等都会用到文件列表table&#xff0c;所以直接封装成组件。 src/components/Table.vue <template><!-- 表格 --><div><el-tableref"dataTable":data"dataSource.list || []":h…

关于在ubuntu18.04中运行ORB_SLAM3时遇到的报错:段错误(核心已转储)的解决方法(踩坑记录)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、段错误&#xff08;核心已转储&#xff09;1. 已放弃(核心已转储)(1) 问题描述(2)原因分析 二、解决方法1. 解决方法一2. 解决方法二 总结 一、段错误&#xff…

Vditor集成于VUE笔记

文章目录 前言一、安装Vditor二、渲染markdown三、options3.1 自建CDN3.2 outline大纲不显示、不跳转问题3.3 upload 图片/视频上传3.4 toolbar提示位置点击事件more中文字 3.5 sv分屏渲染模式隐藏编辑框3.6 after中的insertValue或者setValue 前言 Vditor是一款易于使用的 Ma…

大学生体质测试|基于Springboot+vue的大学生体质测试管理系统设计与实现(源码+数据库+文档)

大学生体质测试管理系统 目录 基于Springboot&#xff0b;vue的大学生体质测试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算…

WebRTC实现多人通话-Mesh架构【保姆级源码教程】

一、Mesh架构 WebRTC&#xff08;Web Real-Time Communications&#xff09;中的Mesh架构是一种将多个终端之间两两进行连接&#xff0c;形成网状结构的通信模式。以下是关于WebRTC的Mesh架构的详细解释&#xff1a; 基本概念&#xff1a;在Mesh架构中&#xff0c;每个参与者…

【QT】QT背景介绍

本专栏内容为&#xff1a;QT学习专栏 通过本专栏的深入学习&#xff0c;你可以了解并掌握QT。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;QT &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f…

Nios-II编程入门实验

文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 …

树莓派点亮FPGA小灯

树莓派点亮FPGA小灯 引言&#xff1a; ​ 本次实验的目的是通过树莓派和FPGA之间的串口通信&#xff0c;控制FPGA开发板上的小灯。实验将展示如何使用树莓派发送特定的字符信号&#xff0c;通过串口传输至FPGA&#xff0c;并在FPGA上实现逻辑解析&#xff0c;以点亮指定的小灯。…

如何在Mac 电脑上安装 Homebrew

1、打开终端应用程序 在终端中输入以下命令并回车: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 这个命令会自动下载并运行 Homebrew 的安装脚本。 系统可能会提示您输入管理员密码,请输入您的 Mac 登录…

java异常,日志,线程堆栈与Jvm调优

一.知识目录&#xff1a; 二.什么是java异常&#xff1a; 2.1 Throwable类中的重要方法: (1)四个构造方法&#xff08;用来构造throwable对象&#xff0c;不同构造方法可以传递不同的参数值&#xff09;&#xff1a; /** 构造一个将 null 作为其详细消息的新 throwable */ Thr…

BGP学习一:关于对等体建立和状态组改变

目录 一.BGP基本概念 &#xff08;1&#xff09;.BGP即是协议也是分类 1.早期EGP 2.BGP满足不同需求 3.BGP区域间传输的优势 &#xff08;1&#xff09;安全性——只传递路由信息 &#xff08;2&#xff09;跨网段建立邻居 4.BGP总结 5.BGP的应用 &#xff08;1&#…

MySQL-索引篇

文章目录 什么是索引&#xff1f;索引的优缺点索引底层数据结构选型Hash表二叉查找树AVL树红黑树B树&B树 索引类型总结主键索引二级索引聚集索引与非聚集索引聚集索引非聚集索引 覆盖索引与关联索引覆盖索引联合查询最左前缀匹配原则 索引下推如何正确使用索引选择合适的字…

Linux基础命令(续)

17&#xff0c;wc命令 作用&#xff1a;统计行数、单词数、字符个数 格式&#xff1a; wc 选项 文件 wc passwd 26 36 1159 passwd26&#xff1a;行数 36&#xff1a;单词数 1159&#xff1a;字符数 passwd&#xff1a;文件名wc autofs.conf 426 2604 15137 autofs.conf426…

CentOS7 安装 Kamailio

https://www.kamailio.org/wiki/packages/rpms 官方文档说 yum -y install yum-utils yum-config-manager --add-repo https://rpm.kamailio.org/centos/kamailio.repo 但目前这样其实行不通 需要这样做&#xff1a; yum install --disablerepokamailio --enablerepokamai…