Java学习第六章(二)

视频链接:https://www.bilibili.com/video/BV1Rx411876f?p=1

视频范围P606 - P628

1.基础类型对应的八个包装类

  1. java中为8种基本数据类型又对应准备了8种包装类型,8种包装类属于引用数据类型,父类是Object
  2. 疑问:为什么要再提供8种包装类?
    答:因为8种基本数据类型不够用,所以SUN又提供对应的8种包装类型

1.1 概念

需求:调用doSome()方法的时候需要传一个数字进去,但是数字属于基本数据类型,而doSome()方法参数的类型是Object
解决方案:传一个数字对应的包装类进去

自定义的包装类

package String.integer;

public class MyInt {
    int value;

    public MyInt() {
    }

    public MyInt(int value) {
        this.value = value;
    }
    
    //重写String
    public String toString(){
        return String.valueOf(value);
    }
}

测试类

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //把100这个数字经过构造方法包装成对象
        MyInt myInt = new MyInt(100);

        //doSome()方法虽然不能直接传100,但是可以传一个100对应的包装类型
        doSome(myInt); //输出为:100
    }

    private static void doSome(Object obj) {
        System.out.println(obj);
    }
}

总结:上面的包装类是自己写的,实际开发种不需要自己写,8种基本数据类型对应的8种包装类,SUN公司已经写好了,直接用!

1.2 八个包装类

基本数据类型包装类型
bytejava.lang.Byte(父类Number)
shortjava.lang.Short(父类Number)
intjava.lang.Integer(父类Number)
longjava.lang.Long(父类Number)
floatjava.lang.Float(父类Number)
doublejava.lang.Double(父类Number)
booleanjava.lang.Boolean(父类Object)
charjava.lang.Character(父类Object)

1.3 装箱和拆箱

  1. 八种包装类种其中6个都是数字对应的包装类,她们的父类都是Number,可以先研究Number中公共的方法
  2. Number是一个抽象类,无法实例化对象
  3. Number类中有下面的方法,这些方法其实所有的数字包装类的子类都有,这些方法是负责拆箱
修饰符类型方法描述
bytebyteValue()返回指定号码作为值 byte ,这可能涉及舍入或截断
abstractdoubledoubleValue()返回指定数字的值为 double ,可能涉及四舍五入
abstractfloatfloatValue()返回指定数字的值为 float ,可能涉及四舍五入
abstractintintValue()返回指定号码作为值 int ,这可能涉及舍入或截断
abstractlonglongValue()返回指定数字的值为 long ,可能涉及四舍五入或截断
shortshortValue()返回指定号码作为值 short ,这可能涉及舍入或截断
package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //123这个基本数据类型,进行构造方法的包装达到了:基本数据类型向引用数据类型的转换
        //基本数据类型--(转换为)-->引用数据类型(装箱)
       Integer i = new Integer(123);

        //引用数据类型--(转换为)-->基本数据类型(拆箱)
       float f = i.floatValue();
        System.out.println(f);//输出为:123.0

        //引用数据类型--(转换为)-->基本数据类型(拆箱)
        int retValue = i.intValue();
        System.out.println(retValue);//输出为:123
    }
}

1.4 以Integer包装类和Double包装类为例

Integer类的构造方法有两个:Integer(int)、Integer(String)

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //Java9之后不建议使用这个构造方法了,出现横线表示已过时了
        //将数字100转换成Integer包装类型(int--->Integer)
       Integer x = new Integer(100);
        System.out.println(x);//输出为:100

        //将String类型的数字转换成Integer包装类型(String--->Integer)
        Integer y = new Integer("211");
        System.out.println(y);//输出为:211
        
        //(double--->Double)
        Double z = new Double(1.11);
        System.out.println(z);//输出为:1.11

       //(String--->Double)
        Double e = new Double("3.14");
        System.out.println(e);//输出为:3.14
    }
}

1.5 通过常量获取最大值和最小值

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //通过访问包装类的常量,来获取最大值和最小值
        System.out.println("int的最大值:" + Integer.MAX_VALUE);//输出为:int的最大值:2147483647
        System.out.println("int的最小值:" + Integer.MIN_VALUE);//输出为:int的最小值:-2147483648
        System.out.println("byte的最大值:" + Byte.MAX_VALUE);//输出为:byte的最大值:127
        System.out.println("byte的最小值:" + Byte.MIN_VALUE);//输出为:byte的最小值:-128
    }
}

1.6 自动拆箱和自动装箱

  1. 在JDK1.5之后,支持自动拆箱和自动装箱
  2. 自动装箱:基本数据类型自动转换成包装类
  3. 自动拆箱:包装类自动转换成基本数据类型
  4. 有了自动拆箱之后,Number类中的方法就用不着了
  5. 自动拆箱和自动装箱的优点:方便编程

代码实例一

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //100是基本数据类型
        //x是包装类型
        //基本数据类型--(自动转换为)-->包装类型:自动装箱
        Integer x = 100;

        //x是包装类型
        //y是基本数据类型
        //包装类型--(自动转换为)-->基本数据类型:自动拆箱
        int y = x;
    }
}

代码实例二

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //z是一个引用,一个变量,还是保存的一个对象的内存地址
        Integer z = 1000;//等价于Integer z = new Integer(1000);
        //+ 两边要求是基本数据类型的数字,z是包装类,不属于基本数据类型
        //这里会进行自动拆箱,将z转换成基本数据类型
        //在java5之前这样写编译器报错
        System.out.println(z + 1);
    }
}

代码实例三

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //a,b都是引用,保存内存地址指向对象
        Integer a = 1000;//等价于Integer a = new Integer(1000);
        Integer b = 1000;//等价于Integer b = new Integer(1000);
        // == 比较的是对象的内存地址,a和b两个引用中保存的对象内存地址不同
        //== 这个运算符不会触发自动插箱机制(只有+-*/等运算的时候才会)
        System.out.println(a == b);//输出为:false
    }
}

内存分析图
在这里插入图片描述
代码实例四

  • java中为了提高程序的执行效率,将【-128~127】之间所有的包装对象提前创建好,放到了一个方法区的“整数型常量池”当中了,目的是只要用这个区间的数据不需要再new了,直接从整数型常量池当中取出来!
  • Integer类加载的时候会初始化整数型常量池:256个对象
  • 池:cache,就是缓存机制
package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        Integer a = 128;
        Integer b = 128;
        System.out.println(a == b);//输出为:false


        Integer x = 127;
        Integer y = 127;
        // == 永远判断的都是两个对象的内存地址是否相同
        System.out.println(x == y);//输出为:true
    }
}

内存分析图
在这里插入图片描述

1.7 Integer中常用方法

1.7.1 intValue()方法

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //手动装箱
        Integer x = new Integer(1000);

        //手动拆箱
        int y = x.intValue();
        System.out.println(y);//输出为:1000
    }
}

1.7.2 Integer包装异常

不是一个数字无法包装成Integer

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        Integer a = new Integer("123");//正确

        //不是一个数字无法包装成Integer
        Integer b = new Integer("中文");//编译正常,运行错误:java.lang.NumberFormatException
    }
}

总结之间所学的经典异常:

  • 空指针异常:NullPointerException
  • 类型转换异常:ClassCastException
  • 数组下标越界异常:ArrayIndexOutOfBoundsException
  • 数字格式化异常:NumberFormatException

1.7.3 static int parseInt(String s)

  1. 静态方法,传参String,返回int
  2. 网页上文本框中输入的100实际上是“100”字符串,后台数据库中要求存储100数字,此时java程序需要将“100”转换成100
package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

       int retValue = Integer.parseInt("123");//String -转换-> int
        //int retValue = Integer.parseInt("中文");//NumberFormatException
        System.out.println(retValue + 100);//输出为:223
    }
}

照葫芦画瓢

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

       double retValue2 = Double.parseDouble("3.14");
       System.out.println(retValue2 + 1);//输出为:4.140000000000001

       float retValue3 = Float.parseFloat("1.0");
       System.out.println(retValue3 + 1);//输出为:2.0
    }
}

1.7.4 将十进制字符串转换为二、八、十六进制字符串

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {


        //静态的:将十进制转换成二进制字符串
        String binaryString = Integer.toBinaryString(3);
        System.out.println(binaryString);//输出为:11

        //静态的:将十进制转换成八进制字符串
        String octalString = Integer.toOctalString(8);
        System.out.println(octalString);//输出为:10

        //静态的:将十进制转换成十六进制字符串
        String hexString = Integer.toHexString(16);
        System.out.println(hexString);//输出为:10
    }
}

1.7.5 valueOf方法

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {
    
        //static Integer valueOf(int i)
        //静态的:int--->Integer
        Integer i1 = Integer.valueOf(100);
        System.out.println(i1);//输出为:100

        //static Integer valueOf(String s)
        //静态的:String--->Integer
        Integer i2 = Integer.valueOf("100");
        System.out.println(i2);//输出为:100
    }
}

1.7.6 String、Integer、int三种类型的互相转换

在这里插入图片描述
String—> int

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        int i1 = Integer.parseInt("100");
        System.out.println(i1 + 1);//输出为:101
    }
}

int—>String

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        int i1 = Integer.parseInt("100");

        String s2 = i1 + "";
        System.out.println(s2 + 1);//输出为:1001
    }
}

int—>Integer

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //自动装箱
        Integer x = 1000;
    }
}

Integer—> int

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        //自动装箱
        Integer x = 1000;
        
        //自动拆箱
        int y = x;
    }
}

String—> Integer

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        Integer k = Integer.valueOf("123");
        System.out.println(k);//输出为:123
    }
}

Integer—> String

package String.integer;

public class IntergerTest01 {

    public static void main(String[] args) {

        Integer k = Integer.valueOf("123");
        String e = String.valueOf(k);
        System.out.println(e);//输出为:123
    }
}

2.日期相关类

  1. 获取系统当前时间
  2. String—>Date
  3. Date—>String

2.1 日期Date概念

package date;

import java.util.Date;

public class DataTest01 {

    public static void main(String[] args) {

        //获取系统当前时间(精确到毫秒的系统当前时间)
        //直接调用无参数构造方法就行
        Date nowTime  = new Date();

        //java.util.Data类的toString()方法已经被重写了
        //输出的不是一个对象的内存地址,应该是一个日期字符串
        System.out.println(nowTime);//输出为:Sun Mar 06 11:08:25 CST 2022
    }
}

2.2 日期格式化

  • 将日期类型Date,按照指定的格式进行转换:Date–转换成具有一定格式的日期字符串–>String
  • SimpleDateFormat是java.text包下的,专门负责日期格式化
package date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DataTest01 {

    public static void main(String[] args) {
        Date nowTime  = new Date();

        /*
        yyyy 年(年是4位)
        MM  月(月是2位)
        dd  日
        HH  时
        mm  分
        ss  秒
        SSS  毫秒(毫秒3位,最高999,1000毫秒代表1秒)
        注意:在日期格式中,除了y M d H m s S这些字符不能随便写之外,剩下的符号格式自己随意组织
         */
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");

        String nowTimeStr = sdf.format(nowTime);
        System.out.println(nowTimeStr);//输出为:2022-03-06 13:25:55 463
    }
}

2.3 将日期字符串String转为Date类型

package date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DataTest01 {

    public static void main(String[] args) throws Exception{

        String time = "2022-02-02 02:02:02 222";
        //格式不能随便写,要和日期字符串格式相同 否则报错:java.text.ParseException
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");

        Date dateTime = sdf.parse(time);
        System.out.println(dateTime);//输出为:Wed Feb 02 02:02:02 CST 2022
    }
}

2.4 获取总毫秒数:currentTimeMillis()

获取自1970年1月1日 00:00:00 000 到当前系统时间的总毫秒数

package date;

public class DataTest01 {

    public static void main(String[] args) throws Exception{

        long nowTimeMillis = System.currentTimeMillis();
        System.out.println(nowTimeMillis);//输出为:1646545407251

    }
}

统计一个方法执行所消耗的时长

package date;

public class DataTest01 {

    public static void main(String[] args) throws Exception{

        //在调用目标方法之前记录一个毫秒数
        long begin = System.currentTimeMillis();

        print();

        //在执行完成目标方法之后记录一个毫秒数
        long end = System.currentTimeMillis();
        
        //这个时长每次运行都会不一样
        System.out.println("耗费时长" + (end - begin) + "毫秒");//输出为:耗费时长38毫秒  
    }

    public static void print(){
        for (int i = 0; i < 10000; i++) {
            System.out.println("i = " + i);
        }
    }
}

2.5 System类的相关属性和方法

属性和方法备注
System.outout是System类的静态变量
System.out.println()println()方法不是System类的,是PrintStream类的方法
System.gc()建议启动垃圾回收器
System.currentTimeMillis()获取自1970年1月1日 00:00:00 000 到当前系统时间的总毫秒数
System.exit(0)退出JVM

2.6 Date(long date)

获取从1970年1月1日 00:00:00 000后的1毫秒

package date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DataTest01 {

    public static void main(String[] args){
        
        Date time = new Date(1);//参数是一个毫秒

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String strTime = sdf.format(time);
        
        //北京是东8区,差8个小时
        System.out.println(strTime);//输出为:1970-01-01 08:00:00 001
    }
}

获取昨天的此时的时间

package date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DataTest01 {

    public static void main(String[] args){

        Date time = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String strTime = sdf.format(time);
        
        System.out.println(strTime);//输出为:2022-03-05 14:07:27 965
    }
}

3.数字相关类

3.1 DecimalFormat

java.text.DecimalFormat:专门负责数字格式化的

package number;

import java.text.DecimalFormat;

public class DecimalFormatTest01 {
    public static void main(String[] args) {
        /*
        数学格式:
        # 代表任意数字
        ,代表千分位
        . 代表小数点
        0 代表不够时补零

        举例:###,###.##  表示:加入千分位,保留2个小数
         */
        DecimalFormat df = new DecimalFormat("###,###.##");

        String s1 = df.format(1234.56);
        System.out.println(s1);//输出为:1,234.56

        String s2 = df.format(1234.56123456);
        System.out.println(s2);//输出为:1,234.56

        //--------------------------------------

        DecimalFormat df1 = new DecimalFormat("###,###.0000");//保留四位小数位,不够补上0
        String s3 = df1.format(1234.56);
        System.out.println(s3);//输出为:1,234.5600
    }
}

3.2 BigDecimal

  • java.math.BigDecimal
  • 属于大数据,精度极高,不属于基本数据类型,属于java对象(引用数据类型),这是SUN提供的一个类,专门用于财务软件当中
  • 财务软件中的double是不够的
package number;

import java.math.BigDecimal;

public class BigDecimalTest01 {

    public static void main(String[] args) {
        //这个100不是普通的100,是精度极高的100
        BigDecimal v1 = new BigDecimal(100);

        //精度极高的200
        BigDecimal v2 = new BigDecimal(200);

        //求和
        //v1和v2都是引用,不能直接使用+求和
        BigDecimal v3 = v1.add(v2);//调用方法求和
        System.out.println(v3);//输出为:300
        
        //求商
        BigDecimal v4 = v2.divide(v1);
        System.out.println(v4);//输出为:2
    }
}

4.Random

4.1 生成随机数

package random;

import java.util.Random;

public class RandomTest01 {
    public static void main(String[] args) {

        //创建随机数对象
        Random random = new Random();

        //随机产生一个int类型取值范围内的数字
        int sum1 = random.nextInt();

        System.out.println(sum1);//输出为:1933396809

        //------------------------------------------
        
        //产生[0~100]之间的随机数,不能产生101
        //nextInt翻译为:下一个int类型的数据是101,表示只能取到100 
        int sum2 = random.nextInt(101);//不包括101
        System.out.println(sum2);//输出为:15
    }
}

4.2 代码实训:生成五个不重复的随机数

需求:编写程序,生成5个不重复的随机数[0-100],重复的话,重新生成。最终生成的5个随机数放到数组中,要求数组中这5个随机数不重复

package random;

import java.util.Arrays;
import java.util.Random;

public class RandomTest01 {
    public static void main(String[] args) {

        //创建Random对象
        Random random = new Random();

        //准备一个长度为5的一维数组
        int[] array = new int[5];

        for (int i = 0; i < array.length; i++) {
            array[i] = -1;
        }

        //循环,生成随机数
        int index = 0;
        while (index < array.length){

            //生成随机数
            int num = random.nextInt(101);

            //判断array数组中有没有这个num,如果没有就放进去
            if (!contains(array,num)){
                array[index++] = num;
            }
        }

        //遍历以上的数组
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }

    /**
     * 单独编写一个方法,这个方法专门用来判断数组中是否包含某个元素
     * @param array 数组
     * @param key 元素
     * @return true表示包含 false表示不包含
     */
    public static boolean contains(int[] array,int key){

        //这个方法有问题
        /*//对数组进行升序
        Arrays.sort(array);

        //进行二分法查找
        //二分法查找结果 >= 0说明这个元素找到了,就表示存在!
        return Arrays.binarySearch(array,key) >= 0;*/

        for (int i = 0; i < array.length; i++) {
            if (array[i] == key){
                return true;
            }
        }
        return false;
    }
}

注意:测试的时候,将int num = random.nextInt(101);改为int num = random.nextInt(6);测试其效果好不好!

5.Enum

  1. 枚举是一种引用数据类型
  2. 枚举语法定义:
enum 枚举类型名{
    枚举值1,枚举值2
}
  1. 结果只有两种情况的,建议使用布尔类型,结果超过两种并且还是可以一枚一枚列举出来的,建议使用枚举类型,例如:颜色,四季,星期等都可以使用枚举类型

5.1 没有使用枚举的情况

下面代码中需要判断divide函数是否成功运行:

package enum2;

public class EnumTese01 {
    public static void main(String[] args) {

        int retValue = divide(10,2);
        System.out.println(retValue == 1?"计算成功":"计算失败");//输出为:计算成功

        int retValue1 = divide(10,0);
        System.out.println(retValue1 == 1?"计算成功":"计算失败");//输出为:计算失败
    }

    /**
     * 需求:以下程序,计算两个int类型数据的商,计算成功返回1,计算失败返回0
     * @param a int类型的数据
     * @param b int类型的数据
     * @return 返回1表示成功,返回0表示失败!!!
     */
    public static int divide(int a,int b){
        try {
            int c = a / b;
            //程序执行到此处表示以上代码没有发生异常,表示执行成功!
            return 1;
        }catch (Exception e){
            //程序执行到此表示以上程序出现了异常,表示执行失败!
            return 0;
        }
    }
}

上面代码中的设计缺陷:

  1. divide函数返回值为Int不恰当,既然最后的结果只是成功和失败,最好使用布尔类型。
  2. 返回"1"或者"0"偏离了需求,实际上已经出错了,但是编译器没有检查出来
  3. 我们一直想追求的是:所有的错误尽可能让编译器找出来,所有的错误越早发现越好!

改正后

package enum2;

public class EnumTese01 {
    public static void main(String[] args) {

        boolean success = divide(10,2);
        System.out.println(success?"计算成功":"计算失败");//输出为:计算成功
    }

    /**
     * 需求:以下程序,计算两个int类型数据的商,计算成功返回true,计算失败返回false
     * @param a int类型的数据
     * @param b int类型的数据
     * @return 返回true表示成功,返回false表示失败!!!
     */
    public static boolean divide(int a,int b){
        try {
            int c = a / b;
            //程序执行到此处表示以上代码没有发生异常,表示执行成功!
            return true;
        }catch (Exception e){
            //程序执行到此表示以上程序出现了异常,表示执行失败!
            return false;
        }
    }
}

思考:当一个方法的执行结果包括三种及以上的时候(每一个都是可以数清楚的,一枚一枚都是可以列举出来的),就需要使用枚举类型

5.2 使用枚举方法一

package enum2;

public class EnumTese02 {
    public static void main(String[] args) {

        Result r = divide(10,2);
        System.out.println(r == Result.SUCCESS?"计算成功":"计算失败");//输出为:计算成功

    }

    /**
     * 计算两个int类型数据的商
     * @param a  int数据
     * @param b  int数据
     * @return  Result.SUCCESS表示成功 Result.FATL表示失败
     */
    public static Result divide(int a, int b){
        try{
            int c = a / b;
            return Result.SUCCESS;
        }catch (Exception e){
            return Result.FATL;
        }
    }
}

//枚举:一枚一枚可以列举出来的,才建议使用枚举类型
//枚举编译之后也是生成class文件
//枚举也是一种引用数据类型
//枚举中的每一个值可以看作是常量
enum Result{
    //SUCCESS 是枚举Result类型中的一个值
    //FATL  是枚举Result类型中的一个值
    //枚举中的每一个值,可以看做是“常量”

    SUCCESS,FATL
}

5.3 使用枚举方法二

  1. switch语句支持枚举类型
  2. switch也支持String,int
  3. 低版本的JDK,只支持int
  4. 高版本的JDK,支持int,String,枚举
  5. byte,short,char也可以,因为存在自动类型转换

枚举类

package enum2;

public enum Season {
    SPRING,SUMMER,AUTUMN,WINTER
}

测试类

package enum2;

public class SwitchTest {

    public static void main(String[] args) {

        switch (Season.SPRING){
            //必须省略Season
            case SPRING:
                System.out.println("春天");
                break;
            case SUMMER:
                System.out.println("夏天");
                break;
            case AUTUMN:
                System.out.println("秋天");
                break;
            case WINTER:
                System.out.println("冬天");
                break;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值