【Java】三个特殊类——Object类、包装类、String类

目录

一、Object类

1、equals方法的复写

2、使用java.util.Comparator接口

二、包装类

1、包装类和基本类型的相互转换

(1)基本类型->包装类对象

(2)包装类对象->基本类型

(3)转换的实现

2、包装类的缓存问题

三、String类

1、字符串的常用方法

(1)字符串的构造方法

(2)字符串对象的比较

(3)字符串查找

 (4)字符串与其他类型的转换问题

(5)字符串格式化

 (6)字符串替换操作

 (7)字符串截取

(8)字符串拆分

 2、字符串常量池的理解

(1)字符串对象的产生方式

(2)intern方法

 3、字符串的不可变性

(1)字符串不可变性的体现

 (2)探究字符串不可变的本质原因

 (3)理解为何字符串的对象设置为不可变对象

4、StringBuffer和StringBuilder


一、Object类

Object是所有的类的父类,不需要声明,所有对象都可以由Object来接收(包括自己新建的类),可以复写Object中的类。

1、equals方法的复写

“==”进行的是两个变量数值的比较,对于基本数据类型来说比较的就是基本数值是否相等,对于引用数据类型来说比较的是两个引用是否指向同一个对象(即地址是否相同)。

equals方法进行的是两个类对象的属性值比较,若类的对象需要具体比较属性值是否相等需要复写Object类中提供的equals方法。

public class ObjectTest {
    public static void main(String[] args) {
        Person person = new Person("洋洋",22);
        Person person1 = new Person("洋洋",22);
        System.out.println(person==person1);
        System.out.println(person.equals(person1));
    }
}
class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public boolean equals(Object obj) {
        if(this==obj){
            return true;
        }
        if(obj ==null || !(obj instanceof Person)){
            return false;
        }
        Person obj1 = (Person) obj;
        if(this.age==obj1.age&&this.name.equals(obj1.name)){
            return true;
        }
        return false;
    }
}

 在Person类中重写了Object类的equals方法,使该方法能比较对象的属性值。在方法中this.name.equals(obj1.name)并不是递归,this.name是String类型。String类中的equals方法系统已经重写可以直接调用。

包装类,String类和集合类的equals的复写已经在系统中实现可以直接调用。 

2、使用java.util.Comparator<T>接口

要比较的类本身并不实现这个接口,实现Comparator接口的类就表示作为该类的比较器。

将要比较的类和具体的比较“策略”解耦思想=>策略模式。

如果需要进行按照成绩的生序排序则传入升序的比较器。

若需要按照成绩降序排序,传入降序的比较器。

比较器都是不同的对象,和要比较的类入Student类是不同的类。

class Student {
    private String name;
    private int age;
    private int score;
    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
    public int getScore() {
        return score;
    }
}
class StudentSec implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getScore() - o2.getScore();
    }
}
class StudentDesc implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.getScore() - o1.getScore();
    }
}
    public static void main(String[] args) {
        Student s1 = new Student("佳佳", 22, 70);
        Student s2 = new Student("洋洋", 24, 66);
        Student s3 = new Student("达达", 18, 80);
        Student s4 = new Student("小昱", 24, 90);
        Student[] students = new Student[]{s1,s2,s3,s4};
        Arrays.sort(students,new StudentDesc());
        System.out.println(Arrays.toString(students));
        Arrays.sort(students,new StudentSec());
        System.out.println(Arrays.toString(students));
    }

二、包装类

JDK中的包装类分为两种:

Object的直接子类,char的包装类Character和boolean的包装类Boolean。

Number的直接子类,整型byte(Byte)、short(Short)、int(Integer)、long(Long)和浮点型float(Float)、double(Double)

1、包装类和基本类型的相互转换

(1)基本类型->包装类对象

成为装箱,通过相应包装类的构造方法或者valueOf方法。

(2)包装类对象->基本类型

成为拆箱。调用相应包装类的xxValue方法实现拆箱。

(3)转换的实现

public static void main(String[] args) {
        int a = 10;
        Integer i1 = Integer.valueOf(a);
        int b = i1.intValue();
        System.out.println(b+1);
    }

任何一个数值型包装类都具有以下这六个方法的实现,可以方便将某个类型转为任意其他类型。

包装箱的装箱和拆箱解决了将基本类型封装到类之中的问题,这就引入了一个新的问题,若需要进行基本类型的运算,需要来回装箱和拆箱很麻烦,所以在JDK编译阶段引入自动拆装箱。

public static void main(String[] args) {
        int a = 10;
        int ret = a+1;
        System.out.println(ret);
        Integer i1 = 10;
        Integer ret1 = i1+1;
        System.out.println(ret1);
    }

 有了自动拆装箱后,使用包装类和使用基本类型用法上没什么区别。阿里编码规范:对于基本的POJO类(自定义类),成员变量统一使用包装类,方法中的局部变量可以使用基本类型。

基本类型和包装类本质上是两个不同的类型,包装类的本职还是类,对于类来说,默认值null。基本类型的默认值就是各个数据类型的默认值。

2、包装类的缓存问题

包装类仍然是类,要比较属性值是否相等用equals,不能用==。

    public static void main(String[] args) {
        Integer a = 111;
        Integer b = 111;
        Integer c = 130;
        Integer d = 130;
        System.out.println(a==b);
        System.out.println(a.equals(b));
        System.out.println(c==d);
        System.out.println(c.equals(d));

    }

 ==比较的仍然是地址,equals比较的是属性值。

而数值型包装类都会在内部有缓存池。Integer默认缓存-128~127的数值,当第一次装箱时,该数值在缓存池中没有新的对象,产生该对象置入缓存池,若有下一次又有了该数值的装箱,不会产生新的包装类对象,直接将缓存对象返回。所以第一

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

世界级白日梦冠军

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

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

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

打赏作者

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

抵扣说明:

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

余额充值