程序员

Java学习20:Integer、日期类、数字类、随机数、枚举

2020-11-07  本文已影响0人  苦难_69e0

基本数据类型的8种包装类

java种为8种基本数据类型又对应准备了8种包装类型。
8种包装类属于引用数据类型,父类是Object。

为什么要再提供8种包装类呢?
因为8种基本数据类型不够用。所以SUN又提供了对应的8种包装类型。

8种基本数据类型对应的包装类型名是什么?

8种包装类.png

这8种包装类中,重点以java.lang.Integer为代表进行学习,其他类型照葫芦画瓢就行。

8种包装类中其中6个都是数字对应的包装类,他们的父类都是Number,可以先研究一下Number中公共的方法:
Number是一个抽象类,无法实例化对象。
Number类中有这样的方法:
byte byteValue() 以byte形式返回指定的数值
abstract double doubleValue() 以double形式返回指定的数值
abstract float float Value() 以float 形式返回指定的数值
abstract int intValue() 以int形式返回指定的数值
abstract long longValue() 以long形式返回指定的数值
short shortValue() 以short形式返回指定的数值
这些方法其实所有的数字包装类的子类都有,这些方法是负责拆箱的。

//装箱和拆箱的概念
public class Test {
    public static void main(String[] args) {
        //123这个基本数据类型,进行构造方法的包装达到了:基本数据类型向引用数据类型的转换。
        
        //基本数据类型---(转换为)--->引用数据类型(装箱)
        Integer i = new Integer(123);
        
        //将引用数据类型---(转换为)--->基本数据类型(拆箱)
        float f = i.floatValue();
        System.out.println(f);//123.0

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

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

//将数字100转换成Integer包装类型(int--> Intrger)
Integer x = new Integer(100);
System.out.println(x);

//将String类型的数字,转换成Integer包装类型。(String---> Integer)
Integer y = new Integer("123");
System.out.println(y);

Double包装类的构造方法

//double-->Double
Doublex = new Double(1.23);
System.out.println(x);

//String-->Double
Doubley = new Integer("3.14");
System.out.println(y);

通过访问包装类的常量,来获取最大值和最小值

public class Test {
    public static void main(String[] args) {
        System.out.println("int的最大值" + Integer.MAX_VALUE);
        System.out.println("int的最小值" + Integer.MIN_VALUE);
        System.out.println("byte的最大值" + Byte.MAX_VALUE);
        System.out.println("byte的最小值" + Byte.MIN_VALUE);
    }
}

在JDK1.5 之后,支持自动拆箱和自动装箱了。

public class Test {
    public static void main(String[] args) {
        //自动装箱
        //int类型 -自动转换为-> Integer
        Integer x = 100;

        //自动拆箱
        //Integer -自动转换为-> int
        int y = x;
    }
}

面试题:String为什么是不可变的?
我看过源代码,String类中有一个byte[]数组,这个byte[]数组采用了final修饰,因为数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象之后,不可再指向其它对象,所以String是不可变的。
面试题:StringBuffer/StringBuilder为什么是可变的呢?
我看过源代码,StringBuffer/StringBuilder内部实际上是一个byte[]数组,这个byte[]数组没有被final修饰,StringBuffer/StringBuilder的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法 System.arraycopy()....是这样扩容的。所以StringBuffer/StringBuilder适合于使用字符串的频繁拼接操作。

面试题

Integer x =127;
Interger y = 127;
System.out.println(x == y);//true

Integer a =128;
Interger b = 128;
System.out.println(a == b);//false

java中为了提高程序的执行效率,将[-128到127]之间所有的包装对象提前创建好,放到了一个方法区的“整数型常量池”当中了,目的是只要用这个区间的数据不需要再new了,直接从整数型常量池当中取出来。

Integer常用方法

intValue()

//手动装箱
Integer x = new Integer(1000);
//手动装箱
int y = x.intValue();
System.out.println(y);

总结一下之前学过的异常:
空指针异常:NullPointerException
类型转换异常:ClassCastException
数组下标越界异常:ArrayIndexOutOfBoundsException
数字格式化异常:NumberFormatException

重点方法
static int parseInt(String s)
静态方法,传参String,返回int

//String--转换-->int
int retValue = Integer.parseInt(123);
System.out.println(retValue + 100);//223

//照葫芦画瓢
Double retValue2 = Double.parseDouble(3.14);
System.out.println(retValue2 + 1);//4.140000000000001(精度问题)

//继续画瓢
folat retValue3 = Float.parseFloat("1.0");
System.out.println(retValue3 + 1);//2.0

(了解)static String toBinaryString(int i)
静态的:将十进制转换成二进制字符串。

String binaryString = Integer.toBinaryString(3);
System.out.println(binaryString);//"11" 二进制字符串

(了解)String toHexString(int i)
静态的:将十进制转换成十六进制字符串。

//十六进制:1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a
String hexString = Integer.toHexString(16);
System.out.println(hexString);//"10" 十六进制字符串

(了解)static String toOctalString(int i)
静态的:将十进制转换成八进制字符串。

String octalString = Integer.toOctalString(8);
System.out.println(octalString);//"10" 八进制字符串

(了解)valueOf()

//static Integer valueOf(int i)
//静态的:int--->Integer
Integer i1 = Integer.valueOf(100);
System.out.println(i1);

//static Integer valueOf(String s)
//静态的:String--->Integer
Integer i2 = Integer.valueOf("100");
System.out.println(i2);
String Integer int 三种类型是相互转换.png 1.png 2.png

日期类

1.怎么获取系统当前时间
2.String --->Date
3.Date--->String

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

public class Test {
    public static void main(String[] args) throws ParseException {
        //获取系统当前时间(精确到毫秒的系统当前时间)
        //直接调用无参数构造方法就行
        Date nowTime = new Date();

        //java.util.Date类的toString()方法已经被重写了。
        //输出的应该不是一个对象的内存地址,应该是一个日期字符串。
        //System.out.println(nowTime);//Sat Oct 17 21:38:33 CST 2020

        //日期可以格式化么?
        //将日期类型Date,按照指定的格式进行转换:Date--转换成具有一定格式的日期字符串-->String
        //SimpleDateFormat是java.text包下的。专门负责日期格式化的。
        /*
        yyyy 年(年是4位)
        MM 月(月是两位)
        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);

        //假设现在有一个日期字符串String,怎么转换成Date类型?
        //String --> Date
        String time = "2008-08-08 08:08:08 888";
        //这里的格式不能随便写,要和日期字符串格式相同
        //注意:字符串的日期格式和SimpleDateFormat对象指定的日期格式要一致。不然会出现异常:java.text.ParseException
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        Date dateTime = sdf2.parse(time);
        System.out.println(dateTime);//Fri Aug 08 08:08:08 CST 2008
    }
}

简单总结一下System类的相关属性和方法:
System.out 【out是System类的静态变量】
System.out.println()【println()方法不是System类的,是PrintStream类的方法。】
System.gc() 建议启动垃圾回收器
System.currentTimeMills() 获取自1970年1月1日到系统当前时间的总毫秒数。
System.exit(0) 退出JVM

public class Test {
    public static void main(String[] args) {
        //获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数。
        long nowTimeMillis = System.currentTimeMillis();
        System.out.println(nowTimeMillis);

        //统计一个方法执行所耗费的时长
        //在调用目标方法之前记录一个毫秒数
        long begin = System.currentTimeMillis();
        print();
        //在执行完目标方法之后记录一个毫秒数
        long end = System.currentTimeMillis();
        System.out.println("耗费时长" + (end-begin) + "毫秒");
    }

    //需求:统计一个方法执行所耗费的时长
    public static void print(){
        for (int i = 0; i < 1000; i++) {
            System.out.println("i = " + i);
        }
    }
}

通过毫秒构造Date对象

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

public class Test {
    public static void main(String[] args) {
        //这个时间是什么时间?
        //1970-01-01 00:00:00 001
        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

        //获取昨天此时的时间。
        Date time2 = new Date(System.currentTimeMillis() - 1000*60*60*24);
        String strTime2 = sdf.format(time2);
        System.out.println(strTime2);//2020-10-17 09:27:29 599

        //获取去年今天的时间
        //Java中,但凡遇到整数值,都以int作为默认类型
        //int类型的上限根本无法保留一年的毫秒数,会进行缩进补位。
        Date time3 = new Date(System.currentTimeMillis() - 1000L*60L*60L*24L*365L);
        String strTime3 = sdf.format(time3);
        System.out.println(strTime3);
    }
}

数字类

数字格式化(了解)

import java.text.DecimalFormat;

public class Test {
    public static void main(String[] args) {
        //java.text.DecimalFormat专门负责数字格式化的。
        //DecimalFormat df = new DecimalFormat("数字格式");

        /*
            数字格式有哪些?
            # 代表任意数字
            , 代表千分位
            . 代表小数点
            0 代表不够时补0

        */
        DecimalFormat df = new DecimalFormat("###,###.##");//表示:加入千分位,保留2个小数
        String s = df.format(1234.56);
        System.out.println(s);

        String s1 = df.format(1234.569999);
        System.out.println(s1);

        DecimalFormat df2 = new DecimalFormat("###,###.0000");//保留4个小数位,不够补0
        String s2 = df2.format(1234.56);
        System.out.println(s2);
    }
}

高精度BigDecimal

BigDecimal 属于大数据,精度极高。不属于基本数据类型,属于Java对象(引用数据类型),这是SUN提供的一个类。专门用在财务软件当中。

注意:财务软件中double的精度是不够的。

面试题:你处理过财务数据么?用的哪一种数据类型?
千万别说double,说java.math.BigDecimal

//精度极高的100
BigDecimal v1 = new BigDecimal(100);
//精度极高的200
BigDecimal v2 = new BigDecimal(200);
//求和
BigDecimal v3 =v1.add(v2) ;//调用方法求和
System.out.println(v3);//300

BigDecimal v4 =v2.divide(v1) ;//调用方法求商
System.out.println(v4);//2

随机数

public class Test {
    public static void main(String[] args) {
        //创建随机数对象
        Random random = new Random();
        
        //随机产生一个int类型取值范围内的数字
        int num1 = random.nextInt();
        System.out.println(num1);

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

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

import java.util.Random;

public class Test {
    public static void main(String[] args) {
        //创建Random对象
        Random random = new Random();
        //准备一个长度为5的一维数组。
        int[] arr = new int[5];//默认都是0
        for (int i = 0; i < arr.length; i++) {
            arr[i] = -1;
        }

        //循环,生成随机数
        int index = 0;
        while (index < arr.length){
            //生成随机数
            int num = random.nextInt(101);
            //判断arr数组中有没有这个num
            //如果没有这个num,就放进去
            if (!contains(arr,num)){
                arr[index] = num;
                index++;
            }
        }

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

    //单独编写一个方法,这个方法专门用来判断数组中是否包含某个元素
    /**
     * arr 数组
     * key 元素
     * return ture 表示包含 false表示不包含
     * */
    public static boolean contains(int[] arr,int key){
        /*
        //这个方案有bug(排序出问题了)
        //对数组进行升序
        Arrays.sort(arr);
        //进行二分法查找
        //二分法查找的结果 >=0 说明,这个元素找到了,找到了表示存在!
        return Arrays.binarySearch(arr,key) >= 0;
      
        */
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == key){
                return true;
            }
        }
        return false;
    }
}

枚举

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

枚举类型怎么定义,语法格式:
enum 枚举类型名{
枚举值1,枚举值2,......
}

结果只有两种情况的,建议使用类型,结果超过两种并且还是可以一枚一枚列举出来的,建议使用枚举类型。
例如:颜色、星期、四季......

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

上一篇 下一篇

猜你喜欢

热点阅读