0
点赞
收藏
分享

微信扫一扫

Javase--13--常用类

_LEON_ 2022-03-12 阅读 82

13 - 常用类

13 - 1 包装类

1、八种基本数据类型对应的引用——包装类;

在这里插入图片描述

2、通过包装类,就可以调用对应类的方法;

基本数据类型包装类
Boolean 和 Character的直接父类是 Object
booleanBoolean
charCharacter
下面6种,直接父类是 Number
btyeBtye
shortShort
intInteger
longLong
floatFloat*
doubleDouble

13-1-1 包装类和基本数据类型的转换

1、在JDK5前 的手动装箱和手动拆箱

手动装箱

// 装箱 int ---> Integer
int a = 99;
Integer integer01 = new Integer(a);
Integer integer02 = Integer.valueOf(a);

手动拆箱

// 拆箱 Integer ---> int
Integer integer03 = new Integer(66);
int b = Integer.intValue(integer03);

2、JDK5 以后(含JDK5)的自动装箱和自动拆箱

  • 自动装箱底层自动调用 valueOf()方法 ,自动拆箱底层调用的是 intValue()方法

自动装箱

int a1 = 36;
//底层是 Integer integer1 = Integer.valueOf(a1)
Integer integer1 = a1; 

自动拆箱

Integer integer2 = new Integer(666);
//底层 int a2 = Integer.intValue(integer02);
int a2 = integer2;

测试题目

//输出结果是什么?
Object obj1 = true ? new Integer(1) : new Double(2.0);
System.out.println(obj1); //输出 1.0

/*
   注意:
   1、三元运算符是一个整体;
   2、要注意基本数据类型优先级;
*/

13-1-2 包装类和String类型 的转换

1、Integer类型 ----> String类型

Integer a = 888; //自动装箱
/*
  方式1
  注意:
  1、以 a 为基本数值转成的字符串,对原先 a的类型无影响;
*/
String str1 = a + "";

//方式2
String str2 = a.toString();

//方式3
String str3 = String.valueOf(a);

2、String类型 ----> Integer类型

String str4 = "6688";
//方式1 
Integer i1 = Integer.parseInt(str4); //这里用到自动装箱
//方式2
Integer i2 = new Integer(str4); //通过constructor

13-1-3 常用方法

1、方法很多,核心:会查API,要读懂API,松,不建议靠翻译软件去帮助翻译,自己去尽量看英文原档,利用理解,翻译软件除非是有些地方自己真翻译不通再用!!!

13-1-4 经典题目

1、题目1

Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //False
************************************************************
/*
注意:This method will always cache values in the range -128 to 127
老韩给的提示:
   1、如果 i 在 -128~127 之间,就从数组中返回;
   2、如何 i 不在 -128~127 之间,直接返回 new Integer(i);
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
*/
//
Integer m = 1; //底层 Integer.valueOf(1); 看上面源码
Integer n = 1;//底层 Integer.valueOf(1);
System.out.println(m == n); //T
*************************************************************
//
Integer x = 128;//底层 Integer.valueOf(1);
Integer y = 128;//底层 Integer.valueOf(1);
System.out.println(x == y);//F

2、题目2

Integer i11=127;
int i12=127;
//只有有基本数据类型,判断的是值是否相同
System.out.println(i11==i12); // T

13 - 2 String类

1、String对象 用于保存字符串,即一组字符序列;

2、字符串常量对象 —— 双引号括起的字符序列,如:“hello”

3、字符串的字符用 Unicode 字符编码,一个字符占两字节(不区分字母还是汉字);

4、String类图:

在这里插入图片描述

(1)String 实现了 Serializable接口,说明 String 可以串行化,可以在网络传输;

(2)String 实现了 Comparable接口,说明 String对象 可以比较大小;

5、String类 是 final修饰,不能被其他类继承;

6、String 有属性 private final char value[]; 用于存放字符串内容;

  • value 是一个 final 类型, 不可以修改:即 value 不能指向新的地址,但是单个字符内容是可以变化;

13-2-1 String创建对象的两种方式

1、直接赋值:String s = “hsp”;

  • 先从常量池查看是否有 “hsp” 数据空间,如果有,直接指向;如果没有,则重新创建,然后指向。s 最终指向是常量池的空间地址。

2、constructor: String s2 = new String(“hsp”);

  • 先在堆中创建空间,里面有 value属性,指向常量池的 hsp空间;如果常量池没有 “hsp”,重新创建,如果有,直接通过 value指向。最终指向的是堆中的空间地址。

JVM内存分布

在这里插入图片描述

13-2-2 String的经典题

1、关于 intern() 方法

  • 老韩提示:b.intern() 最终返回的是常量池的地址;
public class Test {
    public static void main(String[] args) {
        String a = "song";
        String b = new String("song");
        String c = b.intern();
        System.out.println(a.equals(b));
        System.out.println(a == b);

        /*
        intern()方法解读
         When the intern method is invoked, if the pool already contains a
         string equal to this {@code String} object as determined by
         the {@link #equals(Object)} method, then the string from the pool is
         returned. Otherwise, this {@code String} object is added to the
         pool and a reference to this {@code String} object is returned.
        */
        System.out.println(a == b.intern());// true
        System.out.println(c.toString());
        System.out.println(b == b.intern()); // false
    }
}

内存分布图

在这里插入图片描述

2、这个题目不难,每次看的时候,建议自己动手画一下内存分布图,加深理解;

public class Practice02 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "hspedu";
        Person p2 = new Person();
        p2.name = "hspedu";
        System.out.println(p1.name.equals(p2.name)); //比较内容 true
        System.out.println(p1.name == p2.name); // true
        System.out.println(p1.name == "hspedu"); // true

        System.out.println("*********************");
        String str1 = new String("abc");
        String str2 = new String("abc");
        System.out.println(str1 == str2); //比较对象是否指向同一个对象 false
    }
}

class Person{
    public String name;

    public Person(){}

    public Person(String name) {
        this.name = name;
    }
}

13-2-3 String的特性

1、String是一个 final类,代表不可变的字符序列;

2、字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的;

/*
  * The value is used for character storage.
  松,留意一下:
  1、JDK12 源码里面 String类,用于字符存储的 value数组,改为了 byte类型;
  2、JDK8 源码里面 String类,用于字符存储的 value数组,是 char类型;
*/    

private final byte[] value;

题目

1、问题:创建了几个对象?

String a = "hello" + "abc";
/*
   老韩提示:
   1、编译器不是傻子,做了一个优化,判断创建的常量池对象,是否有引用指向;
   2、String a = "hello" + "abc"; ---> String a = "helloabc";
   
   答案:创建1个对象;
*/

2、问题:创建了几个对象?画出内存图?

  • 创建3个对象
String a = "hello"; //创建 a对象
String b = "abc"; // 创建 b对象
String c = a + b;

/*
   老韩提示:
   1、底层是 StringBuilder sbd = new StringBuilder();
   2、sbd.append(a) ;
   // sbd是在堆中,并且append是在原来字符串的基础上追加的;
   3、sbd.append(b);
   4、String c= sbd.toString();
   最后:其实是 c 指向堆中的对象(String) value[] -> 池中 "helloabc"
   
   总结:
   1、String d = "an" + "wo"; 常量相加,看得是池;
   2、String c = a + b; 变量相加,是在堆中
*/


3、很综合的一个练习题,主要看内存图:

public class Practice05 {
    public static void main(String[] args) {
        Test1 ex = new Test1();
        ex.change(ex.str,ex.ch);
        System.out.print(ex.str + " and ");
        System.out.println(ex.ch);
        //输出: hsp and hava
    }
}

class Test1{
    String str = new String("hsp");
    final char[] ch = {'j','a','v','a'};
    public void change(String str,char[] ch){
        str = "java";
        ch[0] = 'h';
    }
}


内存分布图,松,跟着代码看顺序

在这里插入图片描述

13-2-4 String类常用方法

1、split方法;

  • 在对字符串进行分割时,如果有特殊字符,需要加入 转义符 \ ;

2、compareTo方法;

比较两个字符串的大小,如果前者大,
// 则返回正数,后者大,则返回负数,如果相等,返回 0
// 老韩提示:
// (1) 如果长度相同,并且每个字符也相同,就返回 0
// (2) 如果长度相同或者不相同,但是在进行比较时,可以区分大小
// 就返回 if (c1 != c2) {
//   return c1 - c2;
// }
//(3) 如果前面的部分都相同,就返回 str1.len - str2.len

3、format方法;

/*
  老韩提示:
  1、 %s , %d , %.2f %c 称为占位符
  2、 %s 表示后面由 字符串来替换;
  3、 %d 是整数来替换
  4、%.2f 表示使用小数来替换,替换后,只会保留小数点两位, 并且进行四舍五入的处理
  5、 %c 使用 char类型 替换;
*/

4、String类的方法很多,注意:后续用到,查阅API -----> 这里就体现了 English 的重要性咯,松!!!

13-3 StringBuffer

1、java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删;

2、很多方法与String相同,但是 StringBuffer 是可变长度的;

3、StringBuffer 是一个容器;

StringBuffer类图

在这里插入图片描述

4、老韩提示:

(1)StringBuffer 的直接父类是 AbstractStringBuilder;

(2)StringBuffer 实现了 Serializable接口,即 StringBuffer对象可以串行化(对象可以网络传输,可以保存到文件);

(3)在父类 AbstractStringBuilder 中,有属性 char[] value,该 value数组 存放 字符串内容,引用存放在堆中的;

(4)StringBuffer 是一个 final类,不能被继承;

(5)StringBuffer 字符内容是存放在 char[] value 中,因此在变化(增加/删除),不用每次都更换地址(即不是每次创建新对象),所以效率比 String 高;

  • 提示:松,不用每次都更换地址(即不是每次创建新对象),也就是当空间不够时,有一个扩容机制发挥作用,这里根据 源码 可以找到根据!!!

13-3-1 String 和 StringBuffer

1、String 保存的是字符串常量(存放在常量池中),里面的值不能更改,每次 String类 的更新实际上就是更改地址,效率较低;

  • 注意: private final char[] value;

2、StringBuffer 保存的是字符串变量,里面的值可以更改,每次 StringBuffer 的更新实际上可以更新内容,不用每次更新地址,效率较高。

  • 注意:char[] value; 这个存放在堆中

3、StringBuffer 常用的几个构造器

//无参构造器

StringBuffer sb01 = new StringBuffer();

/*
   看下面源码:
   1、父类 AbstractStringBuilder
   AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }
    
    2、子类 StringBuffer
        public StringBuffer() {
        super(16);
    }
    
    3、可以看见:创建一个 大小为 16的 char[] value ,用于存放字符内容
*/

=====================================================================

// 通过构造器指定 char[] value 的大小
    
StringBuffer sb02 = new StringBuffer(100);

/*
  看下面源码:
  1、父类 AbstractStringBuilder
   AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }
    
    2、子类 StringBuffer
    public StringBuffer(int capacity) {
        super(capacity);
    }
    
    3、可以看到:可以自己通过构造器指定 char[] value 的大小;

*/

========================================================================
//通过 给一个String 创建 StringBuffer, char[] 大小就是 str.length() + 16

StringBuffer sb03 = new StringBuffer("hello");

/*
   看下面源码:
    1、父类 AbstractStringBuilder
   AbstractStringBuilder(int capacity) {
        if (COMPACT_STRINGS) {
            value = new byte[capacity];
            coder = LATIN1;
        } else {
            value = StringUTF16.newBytesFor(capacity);
            coder = UTF16;
        }
    }
    
    2、子类 StringBuffer
     public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
    
    3、可以看到:
    (1)先给 String 创建一个 StringBuffer对象,char[] value 的大小是 str.length + 16;
    (2)通过 append方法,把 str 给添加上;
*/

13-3-2 String 和 StringBuffer 的转换

松,看提示

  • 看源码可能会慢点,但是看源码才是最爽的!!!

1、String ----> StringBuffer

(1)使用 constructor; 注意:返回的才是 StringBuffer对象 ,对传入的字符串本身没有影响;

(2)使用 append方法;

2、StringBuffer —> String

(1)使用 StringBuffer 的 toString方法,返回的是 String;

(2)使用 String 的构造器,实参是 StringBuffer类型;

13-3-3 StringBuffer常用方法

1、append方法 ----> 用于追加 字符串;

2、delete(start,end) ----> 删除 >= start && < end 的字符;(左闭右开)

3、replace(start,end,“xxxx”) ----> 用于替换 指定位置 start ~ end 间的字符; (左闭右开)

4、indexOf(“xxxx”) ----> 查找指定的子串在字符串第一次出现的索引,如果找不到返回-1;

5、s.insert(9,“赵敏”) ------> 在索引为 9 的位置插入 “赵敏”,原来索引为 9;

6、length() -----> 计算字符串长度

练习题1

  • 体现——看源码的重要性
public class Exercise01 {
    public static void main(String[] args) {
        String str = null;
        StringBuffer sb = new StringBuffer();
        /*
        *  提示:
        *  1、这里底层调用了 AbstractStringBuilder 的 appendNull方法
        *  2、看源码
        *private AbstractStringBuilder appendNull() {
         ensureCapacityInternal(count + 4);
         int count = this.count;
         byte[] val = this.value;
         if (isLatin1()) {
            val[count++] = 'n';
            val[count++] = 'u';
            val[count++] = 'l';
            val[count++] = 'l';
        } else {
            count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
        }
        this.count = count;
        return this;
    }
        * */
        sb.append(str);
        // 注意:这里计算 StringBuffer sb 的长度不是自己从表面分析的:长度为0;
        System.out.println(sb.length()); //4
        System.out.println(sb); // null
    }
}

练习题2

public class Exercise02 {
    public static void main(String[] args) {
        String str = null;
        /*
        实际执行到这句话:抛出了 NullPointerException
        抛出异常,JVM就中断程序;
        这句话 System.out.println(sb01); 就不会执行
        */
        StringBuffer sb01 = new StringBuffer(str);
        //打印的输出结果是什么?
        /*
        *  1、从表面分析应该打印:null;
        *  2、实际答案是:抛出 NullPointerException
        *  3、在传入 Str 时,会调用 构造器 StringBuffer(String str);
        *  4、答案看源码:
        *     public StringBuffer(String str) {
                  super(str.length() + 16);
                  append(str);
              }

            *5、super(str.length() + 16); 因为传进去的 str 为 null,
            *   因此会 抛出 NullPointerException
        *
        * */
        System.out.println(sb01); 
    }
}

13-3 StringBuilder

1、一个可变的字符序列。

  • StringBuilder 提高一个与 StringBuffer 兼容的API,但不能保证同步(StringBuilder 不是线程安全);
  • StringBuilder 被用作 StringBuffer 的一个简易替换,用在字符串缓冲器被单个线程使用的时候。如果可以,建议优先使用 StringBuilder,因为在多数实现中,它比 StringBuffer 要快。

2、在 StringBuilder 上的操作主要看 append方法 和 insert方法,这些方法可重载;

13-3-1 StringBuilder 的基本知识

1、StringBuilder 继承 AbstractStringBuilder;

2、实现了 Serializable接口 ,说明 StringBuilder 对象是可以串行化(对象可以网络传输,可以保存到文件);

3、StringBuilder 是 final 类;

4、StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder 的 char[] value,因此,字符序列是堆中;

5、StringBuilder 的方法,没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用,效率最高;

13-4 String StringBuffer StringBuilder 的比较

相同点不同点
String不可变字符序列,效率低,但复用率高;
StringBufferStringBuffer and StringBuilder 非常类似,均代表可变的字符序列,方法也基本一致;可变字符序列,效率较高(增删),线程安全(看源码);
StringBuilder可变字符序列,效率最高,线程不安全;

1、String 的使用说明

//创建一个字符串
String s = "a";

/*
  1、实际上原来的 "a"字符串对象 已经丢弃了,现在又产生了一个新字符串 s + "b" (也就是 "ab");
  2、如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。
     如果这样的操作放在循环中,会极大地影响程序的性能。
     
  结论:
  1、对于String类 ,由于多次执行改变字符串内容的操作,导致大量副本字符串存留在内存中,
     因此 String类的复用率高;
     其实更直接的说明 -----> 在 String类中,存放字符串的是 private final char[] value;
  2、但 ----> 如果要对字符串做大量修改,不要使用 String类;
*/
s += "b";

2、String StringBuffer StringBuilder 的效率测试

public class TestEfficiency {
    public static void main(String[] args) {
        long startTime = 0L;
        long endTime = 0L;

        //测试 StringBuffer 效率
        StringBuffer buffer = new StringBuffer("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 200000; i++) { //StringBuffer 拼接 100,000次
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer 的执行时间:" + (endTime - startTime));

        //测试 StringBuilder效率
        StringBuilder builder = new StringBuilder("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 200000; i++) {//StringBuilder 拼接 100,000次
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder 的执行时间:" + (endTime - startTime));

        // 测试String 效率
        String text = "";
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 200000; i++) {//String 拼接 100,000次
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String 的执行时间:" + (endTime - startTime));
    }
}

运行结果

在这里插入图片描述

13 - 5 String StringBuffer StringBuilder 使用选择

使用原则,老韩提示

1、如果字符串存在大量的修改操作,一般使用 StringBuffer / StringBuilder

2、如果字符串存在大量的修改操作,并在单线程的情况下,推荐:StringBuilder

3、如果字符串存在大量的修改操作,并在多线程的情况下,推荐:StringBuffer

4、如果对字符串很少修改,且被多个对象引用,推荐:String,比如配置信息…

13-6 Math类

1、Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

2、Math类的方法均为 static方法,方法具体使用,自己会查API就是 yyds!!!

  • public final class Math
    extends Object
    
    
  • Math类的构造器是 private修饰,因此 Math不能 创建对象;Math类的方法 均为 static方法,可以通过类名直接调用;

  • 松,这也是说明 —— 在自己定义工具类时,便可参考Math类;

13-7 Arrays类

Arrays里包含一系列静态方法,管理或操作数组(如:搜索和排序)

1、toString 返回数组的字符串形式

  • Arrays.toString(arr);
    
    

2、sort排序 —— 自然排序和定制排序

定制排序,有点意思

(1)根据老韩提示走一遍如下

  • public class ArraysExercise01 {
        public static void main(String[] args) {
    
            //sort方法 自然排序和定制排序
            //1、因为数组是引用类型,所以通过 sort 排序后,会直接影响到实参 arr02;
            
            //2、sort 重载的,也可以通过传入一个接口 Comparator 实现定制
            
            //3、调用 定制排序 时,传入两个参数
            //   (1) 排序的数组 arr
            //   (2) 实现了 Comparator 接口的匿名内部类 , 要求实现 compare
            
            //4、源码执行过程
            //(1)Arrays.sort(arr02, new Comparator<Integer>();
            
            //(2)最终到 TimSort类的 static <T> void sort(T[] a, int lo, int hi,                   //      Comparator<? super T> c,T[] work, int workBase, int workLen)
            
            //(3)当执行到 binarySort(a, lo, hi, lo + initRunLen, c);
            //   会根据动态绑定机制 c.compare 执行我们传入的匿名内部类 compare()
            //   private static <T> void binarySort(T[] a, int lo, int hi, int start,
            //                                       Comparator<? super T> c)
            //   while (left < right) {
            //                int mid = (left + right) >>> 1;
            //                if (c.compare(pivot, a[mid]) < 0)
            //                    right = mid;
            //                else
            //                    left = mid + 1;
            //            }
            
            //(4)new Comparator<Integer>() {
            //            @Override
            //            public int compare(Integer o1, Integer o2) {
            //                Integer i1 = (Integer) o1;
            //                Integer i2 = (Integer) o2;
            //                return i1 - i2;
            //            }
            
            //5、可以看到 public int compare(Integer o1, Integer o2) 返回的值 >0 / <0
            //   会影响整个排序的结果
            
            //6、以上:接口编程 + 动态绑定 + 匿名内部类 综合应用
            Integer[] arr02 = {-5,0,89,1,-66};
    
            Arrays.sort(arr02, new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    Integer i1 = (Integer) o1;
                    Integer i2 = (Integer) o2;
                    return i1 - i2;
                }
            });
    
            System.out.println("====排序以后的数组====");
            System.out.println(Arrays.toString(arr02));
    
        }
    }
    
    

定制排序自己实现一遍如下

  • public class ArraysExercise02 {
        public static void main(String[] args) {
            int[] arr = {-5,3,0,1,66,88,-1};
            arraySort(arr, new Comparator() {
                @Override
                public int compare(Object o1, Object o2) {
                    int i1 = (Integer) 01;
                    int i2 = (Integer) o2;
                    return i1 - i2;
                }
            });
            System.out.println("===数组排序以后的顺序===");
            System.out.println(Arrays.toString(arr));
        }
    
        public static void arraySort(int[] arr, Comparator c) {
            int temp = 0;
    //                int arrj01;
    //                int arrj02;
            for (int i = 0; i < arr.length - 1; i++) {
                for (int j = i; j < arr.length - 1; j++) {
    //                int arrj01 = (Integer) arr[j];
    //                int arrj02 = (Integer) arr[j+1];
                    if (c.compare(arr[j], arr[j + 1]) > 0) {
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }
    }
    
    
  • 结果如下:结果有问题,再看时,记得优化

  • 这里就出现一个问题,如果一组数里面有两个 负数,

  • (1)用自己写的正常的冒泡来排序,还是用自己手写的定制排序来排序,都会出现排序不对的情况,我现在还优化不了!

  • (2)但是用 Arrays 提供的sort方法,进行排序,结果没有问题;

在这里插入图片描述

3、binarySearch —— 通过二分搜索法进行查找,要求必须先排好序;

  • /*
     1、要求数组必须为有序数组,若数组是无序的,就不能使用:binarySearch
     2、如果数组中没有相应元素,就返回 return -(low + 1);  // key not found.
    */
    
    

4、copyOf —— 数组元素的复制

  • 老韩提示:

  • /*
       1. 从 arr 数组中,拷贝 arr.length 个元素到 newArr 数组中
       2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null
       3. 如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException
       4. 该方法的底层使用的是 System.arraycopy()
    */
    
    

5、fill —— 数组元素的填充

  • 用一个 num01 去填充数组,也就是 用 num01 去替换原来的元素;

6、equals —— 比较两数组元素是否一致

7、asList —— 将一组值,转为 list;

  • 老韩提示:

  • /*
       1、asList 方法,会将{1, 2, 3, 4, 5, 6} 数据转换位一个 List 集合;
       
       2、看源码,返回 asList 编译类型是: List<T>接口
              public static <T> List<T> asList(T... a) {
                    return new ArrayList<>(a);
              }
              
       3、运行类型:class java.util.Arrays$ArrayList
             这个是 Arrays 的 static内部类,看下面
             private static class ArrayList<E> extends AbstractList<E>
                     implements RandomAccess, java.io.Serializable
    */
    
    public class ArraysExercise03 {
        public static void main(String[] args) {
            Integer[] arr = {1, 2, 3, 4, 5, 6};
            List<Integer> integers = Arrays.asList(arr);
            System.out.println("integerList:" + integers);
            //integers的编译类型是 List(Integer)  看一下运行类型
            System.out.println(integers.getClass());
        }
    }
    
    

13 - 8 System类

1、exit方法: 退出当前程序;

/*
   1、exit(0) 表示程序退出;
   2、0 表示一个状态,正常的状态;
*/
System.exit(0);

2、arrayCopy方法:复制数组元素,比较适合底层调用,一般使用 Arrays.copyOf完成复制数组;

  • public class SystemExercise02 {
        public static void main(String[] args) {
            int[] arr1 = {1,2,3};
            int[] dest = new int[3];
            /*
            * 老韩提示 ——— 也就是明白这5个参数的意思就OK!!!
            *  @param      src      the source array.
             * @param      srcPos   starting position in the source array.
             * @param      dest     the destination array.
             * @param      destPos  starting position in the destination data.
             * @param      length   the number of array elements to be copied.
            * */
           System.arraycopy(arr1,0,dest,0,arr1.length);
           System.out.println(Arrays.toString(dest));
        }
    }
    
    

3、currentTimeMillens:返回当前时间距离 1970-1-1 的毫秒数;

4、gc:运行垃圾回收机制,System.gc();

13-9 BigInteger and BigDecimal类

1、BigInteger:适合保存比较大的整型;

2、BigDecimal:适合保存精度更高的浮点数(小数);

3、BigInteger and BigDecimal常用方法

(1)add 加

(2)subtract 减;

(3)multiply 乘;

(4)divide 除;

BigInteger练习代码,对四个方法结合源码,有相应说明,要看看

  • public class BigIntegerExercise01 {
        public static void main(String[] args) {
    //        int i = 99999999999999999999999999999999999999999999111111;
            /*
            *  1、看类图:BigInteger 和 BigDecimal 直接父类是 Number ----> Object
            *  2、构造器是:
            *     public BigInteger(String val) {
                      this(val, 10);
                   }
            * */
            
            BigInteger bigInteger = new BigInteger("9999999999999999999999999999" +
                    "9999999999999999111111");
            BigInteger bigInteger1 = new BigInteger("100000");
            
            /*
             * add(): 方法有重载,具体返回类型,要看具体调用的方法的源码
             * */
    //        bigInteger = bigInteger.add(bigInteger1);
    //        System.out.println(bigInteger);
    
    //        System.out.println("**********************");
            /*
             * subtract(): 方法有重载,具体返回类型,要看具体调用的方法的源码
             * */
    //        bigInteger = bigInteger.subtract(bigInteger1);
    //        System.out.println(bigInteger);
    
            /*
            * multiply():方法有重载,具体返回类型,要看具体调用的方法的源码
            * */
    //        bigInteger = bigInteger.multiply(bigInteger1);
    //        System.out.println(bigInteger);
    
            /*
            *  Returns a BigInteger whose value is {@code (this / val)}
            *  注意:得到的结果是去掉了小数部分;
            * */
            bigInteger = bigInteger.divide(bigInteger1);
            System.out.println(bigInteger);
    
    
        }
    }
    
    

BigDecimal练习代码,主要调用 divide方法,要注意一下

  • public class BigDecimalExercise01 {
        public static void main(String[] args) {
            double i = 32.22222225555555555555111111111333333888888888d;
            System.out.println(i);
            /*
            * BigDecimal的
            * 1、add()  subtract()  multiply()
            * 2、divide()要注意,有时计算可能会抛出异常
            *      ArithmeticException: Non-terminating decimal expansion;
            *              no exact representable decimal result.
            *
            * 3、在调用 divide()方法时,指定精度即可. BigDecimal.ROUND_CEILING
            * */
    
            BigDecimal bigDecimal = new BigDecimal("444444.4444444444444" +
                    "444444444444444444444444444");
            BigDecimal bigDecimal01 = new BigDecimal("2");
            System.out.println(bigDecimal.divide(bigDecimal01,BigDecimal.ROUND_CEILING));
        }
    }
    
    

13 - 10 日期类

13-10-1 第一代日期类 — Date

1、Date: 精确到毫秒,代表特定的瞬间;

2、SimpleDateFormat:格式化和解析日期的类;

(1)允许进行格式化:日期 ----> 文本;

(2)解析(文本 —> 日期)和规范化;

  • //可以把一个格式化的String 转换为 date
     //1、String --> Date,SimpleDateFormat定义的格式要与给的String格式相同,
     //       否则抛出异常:java.text.ParseException
    
    

13-10-2 第二代日期类 – Calendar

1、Calendar类 是一个抽象类,它为特定瞬间与一组比如 YEAR MONTH…等日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法;

  • //1、Calendar类 是抽象类;
    //2、constructor 是private;
    //3、通过 getInstance()方法获得 Calendar对象;
    //4、Calendar没有专门的格式化方法,得自己定义;
    
    

13-10-3 第三代日期类

1、JDK 1.0 包含了一个 java.util.Date类,但是其大多数方法在 JDK 1.1 引入 Calendar类之后被弃用了。但是 Calendar类也存在些问题:

(1)可变性:如日期和时间这样的类应该是不能变的;

(2)偏移性:Date 中的年份是从 1900年 开始的,月份是从 0 开始的;

(3)格式化:格式化只对 Date有用,而 Calendar则不行;

(4)Date Calendar不是线程安全的,不能处理闰秒(每隔两天,多出1秒)等;

2、LocalDate(日期/年月日),LocalTime(日期/时分秒),LocalDateTime(日期/年月日时分秒)---- JDK8加入

(1)LocalDate(日期/年月日):只包含日期,可以获得日期字段;

  • /*
           *  1、LocalDate 是 final类;
           *  2、constructor 是 private修饰;
           *  3、通过 now()方法 获得日期对象
           *     说明:Obtains the current date from the system clock 
                                    in the default time-zone.
           *      
                  public static LocalDate now() {
                      return now(Clock.systemDefaultZone());
                  }
           * */
    
    

(2)LocalTime(日期/时分秒):只包含时间,可以获得时间字段;

(3)LocalDateTime(日期/年月日时分秒):包含 日期 + 时间,可以获得 日期和时间 的字段;

  • /*
            *  1、LocalDateTime 是 final类;
            *  2、constructor 是 private修饰;
            *  3、通过 now()方法 获得日期时间对象
            *     说明:Obtains the current date-time from the system clock in the default time-zone.
            *      
                  public static LocalDateTime now() {
                       return now(Clock.systemDefaultZone());
                  }
                   
            * */
    
    

3、DateTimeFormat ----》格式日期类;

  • /*
            *  DateTimeFormatter
            *  1、是 final类;
            *  2、constructor 是私有的;
            *  3、通过 ofPattern()方法 获得 DateTimeFormatter对象
            *
            *     public static DateTimeFormatter ofPattern(String pattern) {
                    return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();                      
                  }
            * */
    
    

4、Instant ----》 时间戳

  • Date 与 Instant 的转换

  • public class InstantExercise01 {
        public static void main(String[] args) {
            Instant instant = Instant.now();
            System.out.println(instant);
            //通过 Date类 static from()方法,可以把 Instant 转换为 Date
            Date from = Date.from(instant);
            System.out.println(from);
    
            //通过 Date 的 toInstant方法 把 date 转为为 Instant对象
            Date date = new Date();
            Instant instant1 = date.toInstant();
            System.out.println(instant1);
        }
    }
    
    

5、演示的几个方法,其他方法,到时用的时候,自己 查API 就可了;

  • // plus()  minus() 对当前时间进行加减
    
    
举报

相关推荐

0 条评论