目录

基本类型

引用数据类型

基本类型之间的比较

基于Comparable的比较

总结


👑作者主页:Java冰激凌 📖专栏链接:Java

基本类型

         Java中提供了基本类型有八种 分别是 byte short int long float double char boolean

         基本类型的值可以直接储存在一个变量里,直接在变量上完成一些基本运算,例如相加、逻辑比较、位运算等。下面是一个Java程序的示例代码,展示了如何使用基本类型

public class BasicTypesExample {

    public static void main(String[] args) {
        byte b = 100;       // 声明并初始化一个byte变量
        short s = 200;      // 声明并初始化一个short变量
        int num = b + s;    // 整型变量num表示b和s的和
        System.out.println("b + s = " + num);

        double d = 2.34;    // 声明并初始化一个双精度浮点型变量
        float f = 3.12f;    // 声明并初始化一个单精度浮点型变量
        double result = d * f;  // 计算结果
        System.out.println("d * f = " + result);

        char ch = 'a';      // 声明并初始化一个字符型变量
        boolean flag = true;// 声明并初始化一个布尔型变量
        System.out.println("字符 " + ch + " 是否是小写字母?" + Character.isLowerCase(ch)); // 使用Character类中的isLowerCase()方法判断ch是否是小写字母
        System.out.println("flag 的反码是 " + !flag); // 取反运算符
    }
}

引用数据类型

        引用类型可以是用户自定义类型 也可以是Java各种包中封装的类型 并且 数组 对象 都是引用类型 所有引用类型的默认值都为null

        引用类型与基本类型不同 引用类型变量保存的是对象的地址,因此对于引用类型变量的比较,需要使用equals()方法或者“==”运算符。


基本类型之间的比较

        在基本类型之间我们可以使用使用“==”来进行比较

public static void main (String[] args) {
        int a = 10;
        int b = 10;
        double c = 10.0;
        double d = 10.0;
        System.out.println("a == b :" + (a == b));
        System.out.println("c == d :" + (c == d));
    }

但是在引用类型中 如果我们想比较两个引用类型的值是否相等 我们就需要借助到equals来比较

public static void main (String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1.equals(s2));
   
    }

并且如果我们使用等号的话 我们输出结果会是false 因为我们在介绍引用类型就已经提到了 我们的引用类型存储的是地址  两个不同的引用去比较是否相等比较的是他们的地址是否相同 当然是不一样的啦 但是还是会存在特殊情况的 我们来看如下的代码

public static void main (String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2);
    }

java 类型class比较 java基本类型比较_开发语言

到了此时 我们的s1 跟 s2比较此处会输出true 这是为何 保存的不是地址嘛  怎么会变的 一样 此时我们可以回顾一下当初讨论的String的不可变性 其中提到了常量池的概念 我们可以借助我们的常量池来解释这个问题 因为我们的“hello”字符串在创建的 时候 会在字符串常量池中也创建出一个hello 在我们对于他引用的时候  我们就会在常量池中查找这个字符串是否存在 如果这个字符串已经存在的话 我们的引用类型的变量就可以直接指向这个常量池中的元素 上述的代码就是因为同时指向了常量池中的hello 所以会出现输出结果为true的结果

那么我们又要提出新的问题 如果我们将s2换成创建一个新的对象呢?

public static void main (String[] args) {
        String s1 = "hello";
        String s2 = new String("hello");
        System.out.println(s1 == s2);
    }

此时我们的输出变为了false  这是为啥嘞 这还是回到我们线程池的解释 我们的s2的确创建了一个新的对象 并且这个对象指向的hello也是常量池中对象 我们可是要记得 如果对于引用类型进行比较 我们比较的是地址哦  虽然s2指向的对象是指向hello的 但是其中还间隔有一共对象哦  那么我们如何验证其中的值是否相等呢  我们还是要用到我们的equals

public static void main (String[] args) {
        String s1 = "hello";
        String s2 = new String("hello");
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
    }

java 类型class比较 java基本类型比较_java_02

如果对于字符串常量池不明确 此处是我们的 String的不可变的博客 其中有这明确的解释

与大佬展开讨论String的不可变性对了 我们的自定义类型是不能使用我们的equals方法的 所以说我们要在我们的自定义类中重写我们的equals方法哦


基于Comparable的比较

        除了使用equals()方法和“==”运算符比较引用类型变量,Java还提供了一个基于接口的比较方式,即使用Comparable接口。该接口定义了一个比较方法compareTo(),用于比较两个对象之间的大小关系。实现Comparable接口需要重写compareTo()方法。该方法需要返回一个整数值,表示当前对象与参数对象的大小关系。如果当前对象比参数对象小,则返回负整数;如果当前对象与参数对象相等,则返回0;如果当前对象比参数对象大,则返回正整数。

        我们来以下的代码演示一下 我们的每个类代表一个学生  如果我们想要对于两个学生类之间做比较 要做一个排序的话 我们就需要借助到我们的Comparable接口实现compareTo方法    

class Student implements Comparable<Student>{
    int id;
    int age;
    String name;

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

    @Override
    public int compareTo (Student o) {
        return this.age - o.age;
    }
}
public class Demo5 {
    public static void main (String[] args) {
        Student zhangSan = new Student(1,14,"zhangsan");
        Student liSi = new Student(2,8,"lisi");
        System.out.println(zhangSan.compareTo(liSi));
    }
}

    以上是解决掉了我们的引用类型之间比较其中值的问题 但是也带来了另一个大问题 就是说 我们如果直接在Student类中实现我们的Comparable接口的话  一旦重写compareTo方法 那么我们对于这个类比较的时候就只能使用我们定死的比较规则 这显然是不符合我们代码的“高内聚 低耦合”的 所以说 为了解决这个问题 我们衍生出一个比较器

class Student implements Comparable<Student>{
    int id;
    int age;
    String name;

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

    @Override
    public int compareTo (Student o) {
        return this.age - o.age;
    }
}
class StudentComparable implements Comparator<Student> {
    @Override
    public int compare (Student o1 , Student o2) {
        return o1.age - o2.age;
    }
}
public class Demo5 {
    public static void main (String[] args) {
        Student zhangSan = new Student(1,14,"zhangsan");
        Student liSi = new Student(2,8,"lisi");
        StudentComparable studentComparable = new StudentComparable();
        System.out.println(studentComparable.compare(zhangSan,liSi));
        //System.out.println(zhangSan.compareTo(liSi));
    }
}

此处我们使用了一个类实现了我们的Comparator接口 并且重写了我们的compare方法 这样做的好处是什么呢 这个比较器就可以基于我们要按照从小到大 或者从大到小排序来说 实现我们的比较器 在使用Collection.sort()中就可以传入我们的这个比较器 也可以在其他地方使用我们类之间的比较 实现我们多种比较形式 


总结

Object,equals  :因为Object类是所有类的父类 所以都可以直接调用equals来进行比较其中的值 不过只能比较是否相等 也就是说 返回来类型是boolean类型 

Comparable.compareTo: 需要在类中实现该接口并且重写该方法 但是这么做的话对于代码的侵入性太强 在原则上不满足我们代码的“高内聚 低耦合”

Comparator.compare:需要实现一个比较器对象 使用起来非常灵活对于代码的侵入性很弱