基本类型包装类

141 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

基本类型包装类

Java并不是纯面向对象的语言,虽然Java语言是一个面向对象的语言,但是Java中的基本数据类型却不是面向对象的。在学习泛型和集合之前,基本类型的包装类是一定要讲解的内容!

我们的基本类型,如果想通过对象的形式去使用他们,Java提供的基本类型包装类,使得Java能够更好的体现面向对象的思想,同时也使得基本类型能够支持对象操作!

图片.png

  • byte -> Byte
  • boolean -> Boolean
  • short -> Short
  • char -> Character
  • int -> Integer
  • long -> Long
  • float -> Float
  • double -> Double

包装类实际上就行将我们的基本数据类型,封装成一个类(运用了封装的思想)

private final int value;   //Integer内部其实本质还是存了一个基本类型的数据,但是我们不能直接操作
public Integer(int value) {
    this.value = value;
}

现在我们操作的就是Integer对象而不是一个int基本类型了!

public static void main(String[] args) {
     Integer i = 1;   //包装类型可以直接接收对应类型的数据,并变为一个对象!
     System.out.println(i + i);    //包装类型可以直接被当做一个基本类型进行操作!
}

自动装箱和拆箱

那么为什么包装类型能直接使用一个具体值来赋值呢?其实依靠的是自动装箱和拆箱机制

Integer i = 1;    //其实这里只是简写了而已
Integer i = Integer.valueOf(1);  //编译后真正的样子

调用valueOf来生成一个Integer对象!

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)   //注意,Java为了优化,有一个缓存机制,如果是在-128~127之间的数,会直接使用已经缓存好的对象,而不是再去创建新的!(面试常考)
       return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);   //返回一个新创建好的对象
}

而如果使用包装类来进行运算,或是赋值给一个基本类型变量,会进行自动拆箱:

public static void main(String[] args) {
    Integer i = Integer.valueOf(1);
    int a = i;    //简写
    int a = i.intValue();   //编译后实际的代码
  
    long c = i.longValue();   //其他类型也有!
}

既然现在是包装类型了,那么我们还能使用==来判断两个数是否相等吗?

public static void main(String[] args) {
    Integer i1 = 28914;
    Integer i2 = 28914;
    System.out.println(i1 == i2);   //实际上判断是两个对象是否为同一个对象(内存地址是否相同)
    System.out.println(i1.equals(i2));   //这个才是真正的值判断!
}

注意IntegerCache带来的影响!

思考:下面这种情况结果会是什么?

public static void main(String[] args) {
    Integer i1 = 28914;
    Integer i2 = 28914;
    System.out.println(i1+1 == i2+1);
}

在集合类的学习中,我们还会继续用到我们的包装类型!


面向对象编程实战

虽然我们学习了编程,但是我们不能一股脑的所有问题都照着编程的思维去解决,编程只是解决问题的一种手段,灵活的运用我们所学的知识,才是解决问题的最好办法!比如,求1到100所有数的和:

public static void main(String[] args) {
    int sum = 0;
    for (int i = 1; i <= 100; i++) {   //for循环暴力求解,简单,但是效率似乎低了一些
        sum += i;
    }
    System.out.println(sum);
}
public static void main(String[] args) {
    System.out.println((1 + 100) * 50);  //高斯求和公式,利用数学,瞬间计算结果!
}

说到最后,其实数学和逻辑思维才是解决问题的最终办法!

对象设计(面向对象、多态运用)

  • 设计一个Person抽象类,包含吃饭运动学习三种行为,分为工人、学生、老师三种职业。
  • 设计设计一个接口考试,只有老师和学生会考试。
  • 设计一个方法,模拟让人类进入考场,要求只有会考试的人才能进入,并且考试。

二分搜索(搜索算法)

现在有一个有序数组(从小到大,数组长度 0 < n < 1000000)如何快速寻找我们想要的数在哪个位置,如果存在请返回下标,不存在返回-1即可。

int[] arr = new int[]{1, 4, 5, 6, 7, 10, 12, 14, 20, 22, 26};   //测试用例
private static int test(int[] arr, int target){
    //请在这里实现搜索算法
}

快速排序(排序算法、递归分治)

(开始之前先介绍一下递归!)快速排序其实是一种排序执行效率很高的排序算法,它利用分治法来对待排序序列进行分治排序,它的思想主要是通过一趟排序将待排记录分隔成独立的两部分,其中的一部分比关键字小,后面一部分比关键字大,然后再对这前后的两部分分别采用这种方式进行排序,通过递归的运算最终达到整个序列有序。

快速排序就像它的名字一样,快速!在极端情况下,会退化成冒泡排序!

0/1背包问题(回溯法、剪枝/动态规划优化)

给定 n件物品,每一个物品的重量为 w[n],每个物品的价值为 v[n]。现挑选物品放入背包中,假定背包能承受的最大重量为 capacity,求装入物品的最大价值是多少?

int[] w = {2, 3, 4, 5};
int[] v = {3, 4, 5, 6};
int capacity = 8;