java常用类相关内容

12

1.内部类

概念

  • 在一个类的内部在定义一个完整的类

特点

  • 编译之后可生成独立的字节码文件
    • Outer.class && Outer$Inner.class
  • 内部类可直接访问外部类的私有成员,而不破坏封装
  • 可为外部类提供必要的内部功能组件
/**
 * 内部类四种形式:
 * 1 成员内部类
 * 2 静态内部类
 * 3 局部内部类
 * 4 匿名内部类
 */
public class Outer {
    private String name;
    //内部类:一个类中包含一个完整的类,里层的类称为内部类,外层类称为外部类
    class Inner{

    }
}

分类

成员内部类

  • 在类的内部定义、与实例变量、实例方法同一级别
  • 创建成员内部类对象要依赖外部类对象
    • Outer out = new Outer();
    • Inner in = out.new Inner();
    • 二合一 new Outer().new Inner();
  • 特点
    • 成员内部类可以使用任何访问修饰符
      • 因为成员内部类与实例属性、实例方法同级别
      • 外部类只能用public和默认的
    • 成员内部类可直接访问外部类的属性和方法
      • 因为成员内部类与实例方法同级别
    • 当外部类与内部类存在重名属性时,会优先访问内部类属性,使用“外部类名.this”访问外部类的属性
    • 成员内部类不能定义静态成员(属性和方法)
      • 在类加载的时候,static变量就会被初始化,那么我们Inner对象在没有Outer这个对象的时候便生成了。这样这个成员内部类就脱离了外部类的掌控,不需要外部类的对象就可以生成内部类的对象,这与成员内部类的定义就相驳了,因为我们知道成员内部类的对象必须是现有外部类的对象才能创建,并且是绑定在一起的,所以成员内部类不可以定义静态变量。
      • 成员内部类是和实例方法同级别
      • 在加载Outer外部类的时候,内部类的静态属性就会被初始化,这是不被允许的,因为内部类没有new对象
    • 成员内部类可以包含静态常量
      • static final 特殊不可改变
      • 在外部类加载的时候就已经赋值,将值替换成初始值,不可改变。加载一次,定义了也没有关系
public class Outer {
    //实例属性
    private String name="张三";
    private int age=20;
    //实例方法
    public void show(){
        System.out.println(name+"...."+age);
    }
    //成员内部类:在类的内部定义,与实例变量、实例方法同级别的类。
    //特点:
    /*
    1成员内部类可以使用任意访问修饰符。
    2成员内部类可以直接访问外部类的属性和方法。
    3成员内部类中属性和外部类的属性同名时,使用"外部类名.this"访问外部类的属性
    4成员内部类不能包含静态成员,但是可以包含静态常量。*/
    class Inner{
         private String phone="1316737137";
         private String address="北京";
         private String name="灿灿";

         public void show(){
             System.out.println(phone+"..."+address);
             System.out.println(this.name+"======="+Outer.this.age);
             System.out.println(Outer.this.name+"======="+Outer.this.age);
         }
    }
}
public class Test {
    public static void main(String[] args) {
        //1 创建外部类对象
        /*
        Outer outer=new Outer();
        outer.show();
        //2 创建内部类对象
        Outer.Inner inner=outer.new Inner();
        inner.show();
        */
        //合二为一
        Outer.Inner inner2 = new Outer().new Inner();
        inner2.show();
    }
}

[wppay]

静态内部类

  • static修饰的成员内部类
  • 不依赖外部类对象,可直接创建或通过类名访问,相当于外部类(Outer),为外部类提供功能
    • 学校类里面有一个保安类,保安类可以拿出来,但是放在学校类里面表示只属于这一个学校
  • 特点
    • 可以使用任意访问修饰符
    • 不能直接访问外部类的实例属性和方法需要实例化外部类对象,可直接访问外部类的静态属性和方法
    • 可包含静态成员(静态的属性和方法)
public class Outer {
    private String name = "李四";
    private int age = 18;

    public void show() {
        System.out.println(name + "..." + age);
    }

    private static int count = 10000;
    //静态内部类:不依赖外部类对象,可直接创建或通过类名访问,相当于外部类,为外部类提供功能。
    //特点

    /**
     * 1静态内部类可以使用任意访问修饰符。
     * * 2静态内部类不能直接访问外部类的实例属性和方法,可以直接访问静态的属性和方法。
     * * 3静态内部类可以包含静态成员。
     */
    static class Inner {
        private String phone = "110";
        private String email = "lisi@qq.com";

        public void show() {
            System.out.println(phone + "..." + email);
            Outer outer = new Outer();
            System.out.println(outer.name + "..." + outer.age);
            System.out.println(Outer.count);
        }

        public static void haha() {

        }
    }
}
import com.fq.lz.Day12.day12_2.Outer.Inner;
public class Test {
    public static void main(String[] args) {
        //直接创建静态内部类对象
        Inner inner=new Inner();
        inner.show();
    }
}

局部内部类

定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

特点:

  • 不能使用任何访问修饰符
    • 和局部变量同一级别
  • 如果局部内部类所在方法是实例方法,可以直接访问外部类的实例属性和方法,如果局部类所在的方法是静态方法,不能访问
  • 局部内部类访问上一层的外部类(实例方法)中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
    • JDK1.8之后可以不写final,但不表示没有
    • 为什么加final
  • 局部内部类也不能声明静态成员(静态的属性和方法)、可以使用静态常量
public class Outer {

    private String name = "龙哥";
    private int age = 22;

    public void show() {
        //局部变量
        final int num = 100;
        //局部内部类:定义在外部类方法中,作用范围和创建对象范围仅限于当前方法,限制类的使用范围。
        //特点:
        //1 不能使用任何访问修饰符
        //2 如果局部内部类所在方法是实例方法,可以直接访问外部类的实例属性和方法;如果局部内部类所在方法是静态方法,只能访问外部类的静态属性和方法。
        //3 局部内部类可以访问局部变量,但是局部变量必须是final,JDK1.8 final可以省略 ,对象生命周期长于局部变量。
        //4 局部内部类也不能声明静态成员, 可以使用静态常量
        class Inner {
            private String phone = "120";
            private String email = "longge@qq.com";

            public void innerShow() {
                System.out.println(phone + "...." + email);
                System.out.println(Outer.this.name + "...." + Outer.this.age);
                System.out.println(num);
            }
        }
        //使用局部内部类创建对象
        Inner inner = new Inner();
        inner.innerShow();

    }
}

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

匿名内部类

没有类名的局部内部类,是对局部内部类的优化

  • 一切特征都与局部内部类相同
  • 使用匿名内部类优化局部内部类,实际创建接口实现类,眼看不见
    • 从生成了class文件看
  • 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象

创建方式直接new接口、抽象类的对象

优点:减少代码量。缺点:可读性差

特点

  • 创建匿名内部类可以使用接口、抽象类、普通类、必须实现接口和抽象类中抽象方法
  • 不能手动添加构造方法
    • 没有类名,构造方法要与类名一致。但是他有构造方法
  • 不能包含静态成员
    • 通过类名访问,无法访问
  • 一般不包含特有方法、可以写但是不能直接访问
    • 通过可访问方法(实现的方法)调用
    • 匿名对象调用(见下图)
    • 生成class文件名:外部类名$编号.class

Lambda表达式优化匿名内部类

方法引用优化Lambda表达式

interface Usb {
    void service();
}
class Mouse implements Usb {
    @Override
    public void service() {
        System.out.println("鼠标连接成功,开始工作...");
    }
}

public class Test {
    public static void main(String[] args) {
        Usb usb=new Mouse();
        usb.service();
        //局部内部类,实现接口
        class Upan implements Usb{
            @Override
            public void service() {
                System.out.println("Upan连接成功,开始工作...");
            }
        }
        Usb usb2=new Upan();
        usb2.service();
        //使用匿名内部类优化局部内部类, 实际创建Usb接口实现类对象。
        //特点:
        //1创建匿名内部类可以使用接口,抽象类,普通类,必须实现接口或抽象类中抽象方法。
        //2匿名内部类不能手动添加构造方法, 不能包含静态成员。
        //3匿名内部类中一般不包含特有的方法,不能直接访问,可以通过可访问方法调用或匿名对象调用。
        //4匿名内部类生成的class文件名:外部类名$编号.class
        Usb usb3=new Usb(){
            @Override
            public void service() {
                System.out.println("风扇连接成功,开始工作...");
            }
        };
        usb3.service();
        //Lambda表达式优化匿名内部类
        Usb usb4=()->System.out.println("硬盘连接成功,开始工作...");
        usb4.service();

        //方法引用优化Lambda表达式
    }
}

2.Object类

概念

  • 超类、基类、所有类的直接或间接父类,位于继承树的最顶层
  • 任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
  • 可以作为参数和返回值

Object类中所定义的方法

  • getClass()方法
    • 每个类加载到内存后都有一个类对象,返回引用中存储的实际对象类型
    • 判断两个引用中实际存储对象类型是否一致
  • hashCode()方法
    • 返回该对象的十进制的哈希值 - 理解为对象的地址
    • 根据对象的地址或字符串或数组计算出int类型数值
    • 根据对象的地址或字符串或数组计算出int类型数值
  • toString()方法
    • 返回对象的字符串表示
      • 默认返回 类名@十六进制哈希值:getClass().getName() + "@" + Integer.toHexString(hashCode()
    • 可以根据需求重写该方法,返回对象各个属性
    • 直接打印对象,相当于对象调用了toString()
  • equals()方法
    • 默认实现为(this==obj),比较两个对象的地址
      • 基本数据类型比较值
      • 引用数据类型比较地址
    • 可以重写equals()方法比较属性是否相等
      • 1.判断obj是否为空
      • 2.判断是否是同一个对象
      • 3.判断obj是否是Student类创建的对象
      • 4.比较-向下转型比较属性
      • 快捷键重写
  • finalize()方法
    • 什么样的对象是垃圾对象:没有任何引用的对象
    • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
    • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
    • JDK1.9之后不建议重写
    • 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
    • 手动回收机制:使用System.gc():通知JVM执行垃圾回收

面试题:equals和==的区别

  • equals()是Object中提供的,比较的是地址
  • ==是java运算符,如果是基本类型比较的是值,如果是引用类型比较的是地址
  • 默认Object中的equals()方式的实现与==相同,代码如下:return this==obj
  • 可以在类中重写equals()方法满足特定的需求

字符串的比较用equals()方法,重写了equals方法,比较的是字符数组

public class TestObject {
    public static void main(String[] args) {
        //testGetClass();
        //testHashCode();
        //testToString();
        //testEquals();
        testFinalize();
    }

    //getClass()方法的使用:返回类对象
    public static void testGetClass() {
        Student s1 = new Student("灿灿", 20);
        Student s2 = new Student("龙哥", 22);
        System.out.println(s1.getClass());
        System.out.println(s2.getClass());
        System.out.println(s1.getClass() == s2.getClass());
        if (s1 instanceof Student && s2 instanceof Student) {
            System.out.println(true);
        }
    }

    //hashCode()方法的使用:返回对象的哈希值(理解为对象的地址)
    public static void testHashCode() {
        Student s1 = new Student("灿灿", 20);
        Student s2 = new Student("龙哥", 22);
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
    }

    //toString()方法的使用:返回对象的字符串形式
    public static void testToString() {
        Student s1 = new Student("灿灿", 20);
        Student s2 = new Student("龙哥", 22);
        System.out.println(s1.toString());
        System.out.println(s2.toString());
        System.out.println(s1);//相当于调用toString();
        System.out.println(s2);//相当于调用toString();
    }
    //equals()方法的使用:比较两个对象

    //面试题:equals和==的区别?
    //(1)equals()是Object中提供的方法;==是java种一个运算符,如果是基本类型比的值,引用类比较的是地址。
    //(2)默认Object中的equals方法和 ==一样,代码如下:return this==obj;
    //(3)可以在自定义类中重写equals方法,满足特定的需求。
    public static void testEquals() {
        Student s1 = new Student("灿灿", 20);
        Student s2 = new Student("灿灿", 20);
        boolean b1 = s1.equals(s1);
        boolean b2 = s1 == s2;
        System.out.println(b1);
        System.out.println(b2);
    }

    //finalize()方法的使用: 完成,结束,垃圾回收器回收垃圾对象(没有任何引用的对象称为垃圾对象)之前执行
    public static void testFinalize() {
        Student s1 = new Student("灿灿1", 20);
        Student s2 = new Student("灿灿2", 20);
        Student s3 = new Student("灿灿3", 20);
        Student s4 = new Student("灿灿4", 20);
        Student s5 = new Student("灿灿5", 20);

        s1 = null;
        s2 = null;
        s3 = null;
        s4 = null;
        s5 = null;

        //手动告诉垃圾回收器回收垃圾
        System.gc();//Garbage Collector

    }
}

class Student extends Object {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
    }

    @Override
    public boolean equals(Object obj) {
        //1 判断obj是否为空
        if (obj == null) {
            return false;
        }
        //2 判断是否是同一个对象
        if (this == obj) {
            return true;
        }
        //3判断obj是否是Student
        if (obj instanceof Student) {
            //4 向下转型
            Student s = (Student) obj;
            //5 比较姓名和年龄
            if (this.name.equals(s.name) && this.age == s.age) {
                return true;
            }
        }
        return false;
    }

    //JDK1.9之后不建议重写
    @Override
    protected void finalize() throws Throwable {
        System.out.println(this.name + "..." + this.age + " 被回收了...");
    }
}

3.包装类

基本数据类型对应的引用数据类型

为什么需要包装类?

  • Object可统一所有数据,包装类默认值是null
  • 基本类型功能比较弱

包含内容:

基本数据类型包装成包装类(装箱)

  • 通过包装类的构造器实现
    • int i = 500;Integer t = new lnteger(i);
  • 通过字符串参数构造包装类对象
    • Float f = new Float("4.56");
    • 类型不兼容抛出NumberFormatException

获得包装类对象中包装的基本类型变量(拆箱)

  • 调用包装类的.xxxValue()方法
  • boolean b = Object.booleanValue();

JDK1.5之后支持自动装箱,自动拆箱,类型必须匹配。

  • 自动装箱
    • int count = 1000; Integer a = count;
    • 对应:Integer a =Integer.valueOf(count)
  • 自动拆箱
    • int count2 = a;
    • 对应:int count2 = a.intValue();
  • 如何实现自动装箱和自动拆箱
    • Integer a =Integer.valueOf(count)
    • int count2 = a.intValue();
    • int n1 = 10; Integer a2 = n1; n1==a2的布尔值为true 自动拆箱
      • n1 == n2.intValue()
  • 面试题

整数的缓冲区:缓存数组的范围:-128~127

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

String与基本数据类型与包装类之间的转换:转换的时候可选择进制

字符串转成Boolean类型转换 非“false”或“true”->全是false

    String d2 = "true";
    boolean d3 = Boolean.parseBoolean(d2);

Double 比较存储近似值 不要用大于小于的方式

        Double e1 = 3.14;
        Double e2 = 3.139999;
        //System.out.println(e1 == e2);
        System.out.println(Double.compare(e1, e2));

测试代码:

public class Demo1 {
    public static void main(String[] args) {
        //(1)装箱:把基本类型转成包装类类型
        System.out.println("-----装箱-------");
        //基本类型
        int age=20;
        //创建包装类对象
        Integer integer=new Integer(age);
        System.out.println("age:"+age+" integer:"+integer.toString());
        //(2)拆箱:把包装类类型转成基本类型转成基本类型
        System.out.println("-----拆箱-------");
        Integer integer2=new Integer(200);
        int num=integer2.intValue();
        System.out.println("integer2:"+integer2+" num:"+num);

        //jdk1.5之后,Java支持自动装箱和拆箱
        System.out.println("-----自动装箱------");
        int count=1000;
        //Integer integer3=count;
        Integer integer3=Integer.valueOf(count);
        System.out.println("count:"+count+" integer3:"+integer3);

        System.out.println("-----自动拆箱------");
       // int count2=integer3;
        int count2=integer3.intValue();
        System.out.println("integer3:"+integer3+"count2:"+count2);
        System.out.println("-------------比较-----------------");
        int n1=10;
        Integer integer4=n1;
        System.out.println(n1==integer4);//integer4自动拆箱
        System.out.println("------------面试题---------------");
        Integer integer5=Integer.valueOf(50);
        Integer integer6=Integer.valueOf(50);
        System.out.println(integer5==integer6);// true

        Integer integer7=Integer.valueOf(200);
        Integer integer8=Integer.valueOf(200);
        System.out.println(integer7 ==integer8);//false

        Integer integer9=new Integer(50);
        Integer integer10=new Integer(50);
        System.out.println(integer9==integer10);//false

        //基本类型和字符串之间的转换
        //1 基本类型转成字符串
        System.out.println("------1 基本类型转成字符串------");
        int num2=15;
        String s=num2+"";
        String s2=Integer.toString(num2, 16);
        System.out.println(s);
        System.out.println(s2);

        //2 字符串转成基本类型
        String s3="100";
        System.out.println("------2 字符串转成基本类型------");
        int num3=Integer.parseInt(s3,2);
        System.out.println(num3);

        //3 Boolean类型转换
        String s4="haha"; //"true"--->true , 非"true" 全是false
        boolean b=Boolean.parseBoolean(s4);
        System.out.println(b);

        //Double 比较
        double d1=3.14;
        double d2=3.1399999999999999;
        Double.compare(d1, d2);
    }
}

4.String

概念:

  • 字符串是常量,创建以后不可改变
    • 正常使用不可变,但可以使用反射技术来改变字符串中的数组
  • 从JDK1.9开始底层实现用的是byte[]数组,之前用的是char[]数组

两种创建方式:

  • String s = "asd";
    • 字符串字面值存储在常量池中,可以共享
      • JDK1.7之前字符串常量存放在方法区中的常量池
      • JDK1.7之后移入堆中
    • 方法区在JDK1.8之前也叫永久代,JDK1.8叫元空间
    • 不可变性的理解

相同字符串值的可重复引用

  • String s = new String("asd");

在常量池中实际以数组的方式存储,返回的表示是一个字符串

产生几个对象的问题

  • String s = "hello"; 产生一个对象,在字符串池中存储
  • 产生两个对象
  • 相同字符串值的可重复引用

常用方法

  • equals:比较两个字符串是否相等
  • compareTo():比较字符串的大小,前面的在编码表里的位置,减去后面一个,返回值
  • substring() 方法返回字符串的子字符串。
    • substring(int beginIndex)
    • substring(int beginIndex, int endIndex)
    • 索引从 0 开始
  • intern():保留
    • 判断常量池中有没有,没有则把对象复制一份(或对象引用)放入常量池中,有返回常量池中的对象
    • JDK1.7之前是复制一份放入常量池(方法区),JDK1.7之后则把对象引用复制到常量池(堆中)

String s3 = s1+s2;放在堆里面,String a3 = (new StringBuilder()).append(a1).append(a2).toString();

特例:特殊关键字已经在常量池里面有了

public class Demo4 {
    //字符串中常见方法的使用
    public static void main(String[] args) {
        String s="java是世界上最好的语言,java第一,java真香";
        //charAt();返回某个位置的字符
        char first=s.charAt(0);
        char last=s.charAt(s.length()-1);
        System.out.println(first);
        System.out.println(last);
        //contains;判断字符串中是否包含参数
        boolean b=s.contains("java");
        System.out.println(b);
        //toCharArray();返回字符数组
        char[] chars = s.toCharArray();
        System.out.println(Arrays.toString(chars));
        //indexOf;返回参数字符串在字符串中第一次出现的位置
        int pos=0;
        while((pos=s.indexOf("java", pos))!=-1) {
            System.out.println(pos);
            pos += 4;
        }
        //lastIndexOf();返回最后一个位置
        int posLast=s.lastIndexOf("java");
        System.out.println(posLast);
        //trim() ;去掉字符串前后的空格
        String name="     zhang    san     ";
        String name2=name.trim();
        System.out.println(name);
        System.out.println(name2);
        //replace();替换
        //  " ":空格
        // "" 空字符
        String name3=name.trim().replace(" ", "");
        System.out.println(name3);
        //toUpperCase();把字符串转成大写
        String s2=s.toUpperCase();
        //s.toLowerCase();把字符串转成小写
        System.out.println(s2);
        //endsWith(String str);判断字符串是否以参数结尾
        String filename="hello.java";
        boolean b2=filename.endsWith(".java");
        System.out.println(b2);
        //startWith(String str)判断字符串是否以参数开头
        boolean b3=filename.startsWith("hello");
        System.out.println(b3);
        //split(str);根据str做拆分。
        String content="Java is the    best   language,java first.";
        String[] arr=content.split("[ ,.]+");
        System.out.println(arr.length);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        //substring();截取字符串,含头不含尾
        String sub=s.substring(0, 4);
        String lastsub=s.substring(s.length()-6);
        System.out.println(sub);
        System.out.println(lastsub);

        //equals();比较两个字符是否相等
        System.out.println("hello".equals("hello"));
        //compareTo();比较两个字符串的大小。
        // "abc"  "xyz"   97 - 120  = -23
        System.out.println("xyzabcd".compareTo("xyz"));
    }
}
public class Demo8 {
    public static void main(String[] args) {
        //使用intern方法,把堆中字符串放入常量池。
        // 1如果常量池中没有,则把对象复制一份(或对象引用)放入常量池中,并返回常量池中的对象
        // 2如果常量池中存在,则直接返回。
        //JDK1.7之前是复制一份放入常量池,JDK1.7之后则把对象引用到常量池。
//        String s1="abc";
//        String s2="xyz";
//        String s5="abcxyz";
//        String s3=s1+s2;
//        String s4=s3.intern();
//        System.out.println(s3==s4);
//        System.out.println(s4==s5);
        System.out.println("=========特殊 java void==========");
        //java 、void
        String s1="vo";
        String s2="id";
        String s3=s1+s2;
        String s4=s3.intern();
        System.out.println(s3==s4);
    }
}
public class Demo2 {
    public static void main(String[] args) throws  Exception{
        //字符串:不可变性:字符串变量赋值后,数据不可更改。变量可以重写赋值
        String s1="hello";
        s1="zhangsan";
        String s3="hello";
        System.out.println(s1);

        //使用构造方法赋值
        String name=new String("cancan");
        //面试题1: String name=new String("cancan");在内存创建几个对象? 2个对象


        //面试题2:写出一下结果
        System.out.println("--面试题2:写出一下结果--");
        String add="beijing";
        String add2=new String(add);
        System.out.println(add==add2);//false
        System.out.println(add.equals(add2));//true

        //验证add和add2是同一个数组
        System.out.println("--验证add和add2是同一个数组--");
        //获取value字段
        Field field=add.getClass().getDeclaredField("value");
        //访问权限无效
        field.setAccessible(true);
        //获取数组
        char[] v= (char[]) field.get(add);
        v[0]='B';
        System.out.println(add2);
        //字符串真的是不可变的吗?  正常使用是不可变的,但是可以反射技术来改变字符串中的数组。
    }
}
public class Demo3 {
    public static void main(String[] args) {
        //面试题3:写出一下结果
        String content1="hello";
        String content2="world";
        String content3="helloworld";
        String content4=content1+content2;//堆
        String content5="hello"+"world";
        System.out.println(content3==content4);//false
        System.out.println(content3.equals(content4));//true
        System.out.println(content3==content5);//true
        System.out.println(content3.equals(content5));//true
    }
}
public class Demo5 {
    //需求:已知String str = "this is a text";
    //将str中的单词单独获取出来
    //将str中的text替换为practice
    //在text前面插入一个easy
    //将每个单词的首字母改为大写
    public static void main(String[] args) {
        String str="this is a text";
        //1 将str中的单词单独获取出来
        String[] words=str.split(" ");
        System.out.println(Arrays.toString(words));
        //2将str中的text替换为practice
        String str2=str.replace("text", "practice");
        System.out.println(str2);
        //3 在text前面插入一个easy
        String str3=str.replace("text", "easy text");
        System.out.println(str3);
        //4 将每个单词的首字母改为大写
        String str4="";
        for (int i = 0; i < words.length; i++) {
            String word=words[i];
            char first=word.charAt(0);
            char bigFirst=Character.toUpperCase(first);
            String word2=bigFirst+word.substring(1);
            str4+= word2+" ";
        }
        System.out.println(str4);
    }
}

面试题

第一题:

验证值比较

第二题:

String content4 = (new StringBuilder()).append(c1).append(c2).toString();

String content5 = "helloworld";

可变字符串:StringBuilder和StringBuffer

不同于String,其对象必须使用构造器生成

可在内存中创建可变的缓冲空间,存储频繁改变的字符串

StringBuffer

  • 可变长字符串,JDK1.0提供,运行效率慢,线程安全

StringBuilder

  • 可变长字符串,JDK5.0提供,运行效率快,线程不安全

常用方法:append()、insert()、replace()、delete()

大量的字符串拼接一定要用StringBuilder或者StringBuffer

public class Demo6 {
    //StringBuilder的使用
    public static void main(String[] args) {
        StringBuilder sb=new StringBuilder();
        //StringBuffer sb=new StringBuffer();
        //append();追加
        sb.append("java是世界最好的语言");
        System.out.println(sb.toString());
        sb.append("java第一");
        sb.append("我爱java");
        System.out.println(sb.toString());
        //insert();插入
        sb.insert(0, "我爱北京");
        System.out.println(sb.toString());
        //replace();替换
        sb.replace(0, 4, "helloworld");
        System.out.println(sb.toString());
        //delete();删除
        sb.delete(0, 5);
        System.out.println(sb.toString());
        //清空
        sb.delete(0, sb.length());
        System.out.println("空:"+sb.toString());
    }
}
public class Demo7 {
    public static void main(String[] args) {
        //获取从1970年0时0分0秒的毫秒数
        long start = System.currentTimeMillis();
        String s = "";
        //StringBuilder s = new StringBuilder();
        for (int i = 0; i <= 10; i++) {
            //s = (new StringBuilder()).append(s).append(i).toString();
            s += i;
            //s.append(i);
        }
        //StringBuilder
        System.out.println(s);
        //String
        System.out.println(s.toString());

        long end = System.currentTimeMillis();
        System.out.println(end - start);
        //用时:
        //String 19996
        //StringBuilder 8
    }
}

5.正则表达式

用字符串验证另一个字符串格式是否满足

https://github.com/ziishaned/learn-regex

用途:

  • 匹配 str.matches(reg)
  • 拆分 str.split(reg)
  • 获取
    • 1.编译为Pattern对象 Pattern p = Pattern.compile("[jJ]ava");
    • 2.获取匹配器 Matcher matcher = p.matcher(str);
    • 3.find();查找满足要求的字符串,找到返回true,没有找到返回false
  • 替换 str.replaceAll("[Jj]ava", "php")

应用:

  • 叠词替换 String hi="我..我..我喜喜….喜欢欢….欢JJJava";
  • 去掉点 String hi2 = hi.replaceAll("[.]", "");
  • 去掉重复的 String hi3 = hi2.replaceAll("(.)\1+", "$1");

语法:

public class Demo9 {
    public static void main(String[] args) {
        //Regular Expression
        //1 匹配
        //匹配手机号码
        System.out.println("-----匹配--------");
        String reg="1[3578][0-9]{9}";
        String phone="13167371397";
        boolean b=phone.matches(reg);
        System.out.println(b);
        //匹配QQ邮箱
        String reg2="[1-9][0-9]{4,10}@[qQ]{2}\\.com";
        String qq="113141@QQ.com";
        boolean b2= qq.matches(reg2);
        System.out.println(b2);
        System.out.println("------拆分---------");
        //2拆分
        String str="Java is the best     language,java first.";
        String[] arr=str.split("[ .,]+");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("-------获取-------");
        //3获取(了解)
        //编译为Pattern对象
        Pattern p=Pattern.compile("[jJ]ava");
        //获取匹配器
        Matcher matcher=p.matcher(str);
        //find();查找满足要求的字符串,找到返回true,没有找到返回false
        while(matcher.find()){
            //group()获取满足的数据
            System.out.println(matcher.group());
        }
        //4替换
        System.out.println("---替换----");
        String str2=str.replaceAll("[Jj]ava", "php");
        System.out.println(str2);

        //了解 叠词替换 String hi="我..我..我喜喜....喜欢欢....欢JJJava";  //我喜欢java
        String hi="我..我..我我我喜喜....喜欢欢....欢JJJava";  //我喜欢java
        //1 去掉.
        String hi2=hi.replaceAll("[.]", "");
        //2 去掉重复的
        String hi3=hi2.replaceAll("(.)\\1+", "$1");
//        char[] chars=new char[hi2.length()];
//        chars[0]=hi2.charAt(0);
//        int size=1;
//        for(int i=1;i<hi2.length();i++){
//            char c1=hi2.charAt(i);
//            char c2=hi2.charAt(i-1);
//            //判断chars数组中是否包含符号
//            if(c1!=c2){
//                //放进去
//                chars[size++]=c1;
//            }
//        }
//        String hi3=new String(chars, 0, size);

        System.out.println(hi3);

    }
}

6.BigDecimal类

实现精确计算浮点数 java.math包中

public class Demo1 {
    //BigDecimal的使用:大数字类,作用:实现精确计算
    public static void main(String[] args) {
        //要写字符串,不然可能有误差
        BigDecimal bd1=new BigDecimal("1.0");
        BigDecimal bd2=new BigDecimal("0.9");
        //加   不写toString 默认调用
        BigDecimal result= bd1.add(bd2);
        System.out.println(result.toString());
        //减
        BigDecimal result2=bd1.subtract(bd2);
        System.out.println(result2);
        //乘
        BigDecimal result3=bd1.multiply(bd2);
        System.out.println(result3);
        //除
        BigDecimal bd3=new BigDecimal("5");
        BigDecimal bd4=new BigDecimal("3");
        //HALF_UP四舍五入 HALF_DOWN五舍六入  除不尽报异常,没有指定保留的位数
        BigDecimal result4=bd3.divide(bd4,2, RoundingMode.HALF_UP);
        System.out.println(result4);

        //BigInteger: 大整数类:实现精确计算,做大的数字的计算
        BigInteger bi1=new BigInteger("111111111111111111111111111111");
        BigInteger bi2=new BigInteger("222222222222222222222222222222");
        BigInteger bi3=bi1.add(bi2);
        System.out.println(bi3);
    }
}

7.BigInteger类

大整数类,实现精确计算

8.Math类

public class Demo2 {
    //Math的使用
    public static void main(String[] args) {
        //1绝对值
        System.out.println(Math.abs(100));
        System.out.println(Math.abs(-20));
        //2 求立方根cbrt(double a)
        System.out.println(Math.cbrt(27));
        //3 ceil(double a) 返回大于或等于a的最小整数
        System.out.println(Math.ceil(3.5));
        System.out.println(Math.ceil(4));
        //4 floor(double a) 返回小于或等于a的最大整数
        System.out.println(Math.floor(3.5));
        //5pow(double a, double b)  求次幂
        System.out.println(Math.pow(2, 10));
        //5random() 返回0到1之间的小数,含0不含1
        System.out.println(Math.random());
        //求0-9之间的整数
        System.out.println((int)(Math.random()*10));
        //求50-99之间的整数
        System.out.println((int)(Math.random()*50)+50);
        //求100-999
        System.out.println((int)(Math.random()*900)+100);
        //求15-30
        System.out.println((int)(Math.random()*16)+15);  //(int)(Math.random*(b-a+1))+a
        //6round();四舍五入取整
        System.out.println(Math.round(3.4));
        //3.1415926
        //四种实现四舍五入的方法
        //Math.round 实现保留小数位数
        System.out.println(Math.round(3.1455926*100)/100.0);
        //pintf 实现保留小数位数
        System.out.printf("%.2f",3.1415926);
        System.out.println();
        //BigDecimal 实现保留小数位数
        BigDecimal bd=new BigDecimal("3.1455926");
        BigDecimal bd2=bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println(bd2);
        //DecimalFormat:数字格式化类  #表示整数部分,0表示小数部分,一个0表示一个小数
        DecimalFormat df=new DecimalFormat("#.00");
        String s=df.format(3.1455926);
        System.out.println(s);
    }
}

保留小数位数:

  • 四舍五入取整:Math.round(3.5) -> 4
  • System.out.printf("%.2f",3.1415);
  • BigDecimal
  • DecimalFormat:数字格式化类
        //数字格式化类,#表示整数部分,0表示小数部分有几位
        DecimalFormat format = new DecimalFormat("#.00");

9.Random类

此类的实例用于生成伪随机数流

此类使用48位的种子,使用线性同余公式对其进行修改所得

若long种子确定,则在不同程序中,相同次数产生的随机数是相同的

public class Demo2 {
    public static void main(String[] args) {
        //Random类 有默认种子
        Random random = new Random();
        //nextInt 返回随机整数
        int anInt = random.nextInt();
        System.out.println(anInt);
        //nextInt 返回指定范围的整数 0-99 [ )
        int anInt1 = random.nextInt(100);

        //nextDouble 返回0-1之间的小数,含0不含1
        double aDouble = random.nextDouble();

        //创建指定种子的随机数对象 种子一样生成的序列一样
        Random random1 = new Random(1000);
        Random random2 = new Random(1000);
        for (int i = 0; i < 10; i++) {
            System.out.println(random1.nextInt());
            System.out.println(random2.nextInt());
        }
    }
}

10.Date类

表示瞬间,精确到毫秒,大部分方法失效,被Calender取代

时间单位:

  • 1秒 = 1000毫秒
  • 1毫秒 = 10000微秒
  • 1微秒 = 1000纳秒
public class Demo4 {
    public static void main(String[] args) {
        //Date 表示瞬间,精确到毫秒
        //现在
        Date now=new Date();
        System.out.println(now);
        //昨天
        Date yesterday=new Date(now.getTime()-60*60*24*1000);
        System.out.println(yesterday);
        //after,测试当前日期是否在指定日期之后
        boolean b=now.after(yesterday);
        System.out.println(b);
        //before,测试当前日期是否在指定日期之前
        boolean b2=now.before(yesterday);
        System.out.println(b2);
        //compareTo,比较两个时间的毫秒值,返回值是 1  0 -1
        int r=now.compareTo(yesterday);
        System.out.println(r);
        //equals(Object obj)比较两个时间的毫秒值,如果毫秒值相等true,否则false
        boolean b3=now.equals(yesterday);
        System.out.println(b3);
        Date tomorrow=new Date();
        tomorrow.setTime(tomorrow.getTime()+60*60*24*1000);
        //Wed Mar 17 11:21:57 CST 2021
        System.out.println(tomorrow);
        //2021-3-17 11:21:57
        System.out.println(tomorrow.toLocaleString());
    }
}

11.Calender类

public class Demo4 {
    public static void main(String[] args) {
        //Calender类的使用 特定的瞬间,精确到毫秒
        //创建Calender对象
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH) + 1);
        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
        System.out.println(calendar.get(Calendar.MINUTE));
        System.out.println(calendar.get(Calendar.SECOND));

        //创建昨天
        Calendar yesterday = Calendar.getInstance();
        yesterday.set(Calendar.DAY_OF_MONTH, 15);

        //其他方法
        //add方法
        Calendar tommorrow = Calendar.getInstance();
        tommorrow.add(Calendar.DAY_OF_MONTH, 1);
        System.out.println(tommorrow.get(Calendar.DAY_OF_MONTH));

        //获取精确的最大值
        Calendar month1 = Calendar.getInstance();
        month1.add(Calendar.MONTH, -1);
        System.out.println(month1.getActualMaximum(Calendar.MONTH));
        System.out.println(month1.getActualMinimum(Calendar.MONTH));

        //获取可能最大值
        System.out.println(month1.getMaximum(Calendar.DAY_OF_MONTH));
        System.out.println(month1.getMaximum(Calendar.DAY_OF_MONTH));

        //Calender和Date的转换
        //data->Calender
        Date date = new Date();
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        //Calender->data
        Date time = instance.getTime();
    }
}

12.SimpleDateFormat类

public class Demo6 {
    //SimpleDateFormat:(1)格式化日期  (2)解析日期
    public static void main(String[] args) throws  Exception {
        //(1)格式化日期
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String s=sdf.format(new Date());
        System.out.println(s);
        //(2)解析日期 日期格式不匹配的话报异常:ParseException(解析异常)
        SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd");
        String str="2020-10-1";
        Date data2 = sdf2.parse(str);
        System.out.println(data2);
    }
}

13.System类

系统类,属性和方法都是共享的

public class Demo6 {
    public static void main(String[] args) {
        //System类:系统类,属性和方法都是共享的
        //1.System.arraycopy
        int[] ints = {1, 2, 3, 4, 5, 6, 7};
        int[] ints1 = new int[ints.length * 2];
        System.arraycopy(ints, 0, ints1, 0, ints.length);
        for (int i = 0; i < ints.length; i++) {
            System.out.print(ints1[i] + " ");
        }
        System.out.println();

        //2.System.arraycopy()实现删除元素
        System.arraycopy(ints, 1, ints, 0, ints.length - 1);
        ints[ints.length - 1] = 0;
        for (int i = 0; i < ints.length; i++) {
            System.out.print(ints[i] + " ");
        }
        System.out.println();

        //3.currentTimeMillis() 获取从1970年1月1日 到现在的毫秒值
        //4.nanoTime() 返回最准确的可用系统计时器的当前值,以纳秒为单位
        System.out.println(System.currentTimeMillis());
        System.out.println(System.nanoTime());

        //5.终止当前正在运行的JAVA虚拟机,0正常退出,非0非正常退出
        //System.exit(0);
        //System.out.println("测试执行");

        //6.gc()告诉垃圾回收器回收垃圾
        //System.gc();

        //7.identityHashCode(Object x) 获取对象原始的HashCode
        Name name = new Name();
        System.out.println(name.hashCode());
        System.out.println(System.identityHashCode(name));

        String s = new String("hello");
        String s2 = new String("hello");
        //false
        System.out.println(s == s2);
        //重写了hashCode方法,返回相同
        System.out.println(s.hashCode());
        System.out.println(s2.hashCode());
        //获取原始哈希值
        System.out.println(System.identityHashCode(s));
        System.out.println(System.identityHashCode(s2));
    }
}

class Name {
    String name;
    @Override
    public int hashCode() {
        return 100;
    }
}

14.Runtime类

每一个java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连。可以通过getRunntime方法获取当前运行时。

public class Demo8 {
    //Runtime类的使用:运行时类,获取与当前系统有限的信息
    public static void main(String[] args) throws Exception {
        //获取运行时
        Runtime runtime = Runtime.getRuntime();
        //1 执行命令
        //Process process=runtime.exec("notepad");
        //Thread.sleep(3000);

        //2关闭进程
        //process.destroy();

        //3 终止当前正在运行的java虚拟机
        //runtime.exit(0);
        //System.exit();

        //4 建议JVM赶快启动垃圾回收器回收垃圾
        //runtime.gc();
        //System.gc();

        //5 获取内存信息
        //-Xmx:最大大小
        //-Xms:初始大小
        //-Xss:修改栈空间大小
        //  * jdk1.5之前256k
        //  * jdk1.5之后1m
        System.out.println("总内存大小:" + (runtime.totalMemory() / 1024 / 1024));
        System.out.println("空闲内存:" + (runtime.freeMemory() / 1024 / 1024));
        System.out.println("最大内存:" + (runtime.maxMemory() / 1024 / 1024));
        System.out.println(Arrays.toString(args));
        Thread.sleep(100000);
    }
}

[/wppay]