常用类 四

常用类

1. Object类

1.1 构造方法

public object()

1.2 方法

1.2.1 hashCode

public int hashCode() //打印出一个对象的逻辑地址,相同对象地址一样哈希码肯定相同
无符号十六进制表示:Integer.toHexString(obj.hashCode())

1.2.2 getClass

public final Class<?> getClass()//打印运行时的类,描述类的结构,Class<?>方法的返回值

 //定义一个抽象动物类,狗类继承
 Animal dog = new dog; // 多态
 /*
 多态成员访问特点:
    成员变量: 编译看左边(父类),运行看左边(父类)
    成员方法: 编译看左边(父类),运行看右边(子类)
    静态方法: 编译看左边(父类),运行看右边(父类)
总结:只有非静态的成员方法,编译看左边,运行看右边
 */
 Class clz = dog.getClass();
 System.out.println(clz); //class 包名.Dog -->多态运行时看右边返回Dog没有返回Animal
 System.out.println(clz.getName()); //包名+类名
 System.out.println(clz.getSimpleName);//类名
 Animal cat = new Animal(){ };
 System.out.println(cat.getClass());//class 包名.文件名$1 -->$:匿名内部类 1:第一个匿名内部类
1.2.3 toString

public String toString() //返回对象的字符串,建议重写子类,不重写就会和打印对象返回一样

//toString源码
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
        //组成:类名 + @ + 此对象的哈希码无符号十六进制表示
    }

//toString没有重写
public String toString(){
    return super.toString();//调用上面源代码
}
//重写后,不调用父类
public String toString(){
    return "name: " + name + "age: " + age;
}
1.2.4 equals

public boolean equals(Object obj) //默认比较对象的引用值是否相同,一般建议重写
引用数据类型才有equals方法,类(类型)没有重写equals方法比较的是内存中的地址,如:String,Integer,Date这些类中都有自身的实现

//源码
public boolean equals(Object obj) {
        return (this == obj);
    }
//equals没有重写
public boolean equals(Object obj){
    return super.equals(obj); //调用源码
}
//重写
public boolean equals(Object obj){
    //1.把obj还原成Student
    Student other = (Student)obj;
    retuen this.age == other.age && this.name.equals(other.name);
}

2. 包装类

2.1 定义

将基本数据类型封装成对象,常用于字符串之间的转换
优点:让基本数据类型有对象的特征,定义更多的方法操作该数据
包装类属于引用数据类型

2.2 基本类型对应的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

2.3 int转成字符串

    int a = 100;//把a转成字符串
    Integer integer = new Integer(a);
    String str = integer.toString();

2.4 Integer构造方法

  • Integer(int value);构造一个新分配的Integer对象,它表示指定int值
  • Integer(String str);构造一个新分配的Integer对象,它表示String参数所指示的int值

2.5 Integer静态常量

  • Max_VALUE: 值为2^31 -1 的常量,它表示int类型能够表示的最大值
  • MIN_VALUE: 值为-2^31 的常量,它表示,int类型能够表示的最小值
  • SIZE: 用以二进制补码的形式表示int值的比特位数
  • TYPE: 表示基本类型int的Class实例

2.6 方法

  • toBinaryString(int i); // 把i转成二进制字符串
  • toHexString(int i); // 把i转成十六进制字符串
  • toOctalString(int i); // 把i转成八进制字符串

2.7 int --> String

int a = 10;
//1. 和 "" 进行拼接
String str01 = a + "";
//2. public static String valueOf(int i)//String类方法
String str02 = String.valueOf(a);
//3.int --- Integer --- String(Integer类的toString方法)
Integer integer = a;
String str03 = integer.toString(a);
//4.public static String toString (int i)//Integer类方法
String str04 = Integer.toString(a);
System.out.println(str01+"   "+str01.getClass() + "\n" 
                +str02 +"   " + str02.getClass()+"\n"
                +str03+"   "+ str03.getClass()+"\n"
                +str04+"   "+ str04.getClass());

输出>:  10  class java.lang.String
        10   class java.lang.String
        10   class java.lang.String
        10   class java.lang.String

2.8 String --> int

//1.1.String --> Integer --> int
String str = "520";
Integer int1 = new Integer(str).intValue();
//2.public static int parseInt(String s)
int int2 = Integer.parseInt(str);
System.out.println(int1 +"   " + int1.getClass() + "\n" + int2);

输出>: 520  class java.lang.Integer  520

2.9 自动装箱和拆箱

JDK1.5的新特性自动装箱和自动拆箱
自动装箱:把基本数据类型转换为包装类类型,由虚拟机自动调用Integer.valueOf(String str)方法
自动拆箱:把包装类类型转换为基本数据类型,由虚拟机自动调用Integer.intValue(int Value)方法

Integer int1 = 10; //自动装箱:内部会自动转换为Integer类型 Integer.valueOf(10)
int a = int1; //把Integer赋值给int类型,自动拆箱:内部会调用int1.intValue()

Integer c = null;
int d = c;//java.lang.NullpointerException 自动拆箱:c.intValue()

代码一
    Integer i1 = new Integer(97);
    Integer i2 = new Integer(97);
    System.out.println(i1 == i2); // false: == 比较的是地址,每一个对象的地址都是不同的
    System.out.println(i1.equals(i2));//true: equals重写了父类的equals方法
代码二:(Byte,Short,Integer,Long)
    Integer i1 = 100;
    Integer i2 = 100;
    Integer i3 = 200;
    Integer i4 = 200;
    System.out.println(i1==i2); //true: 自动装箱:值相同则地址一样
    System.out.println(i1.equals(i2)); //true
    System.out.println(i3==i4); //false;自动装箱的范围-128 - 127,如果不在这个范围就不会进入缓存池,就会在外面new
    System.out.println(i3.equals(i4)); //true
代码三:(Double,Float)
    Double d1 = 100.0;
    Double d2 = 100.0;
    Double d3 = 200.0;
    Double d4 = 200.0;
    System.out.println(d1 == d2);  //false
    System.out.println(d1.equals(d2));  //true
    System.out.println(d3 == d4);  //false
    System.out.println(d3.equals(d4)); //true
代码四:(Boolean)
    Boolean bo1 = false;
    Boolean bo2 = false;
    Boolean bo3 = true;
    Boolean bo4 = true;
    System.out.println(bo1 == bo2);  //true
    System.out.println(bo1.equals(bo2));   //true
    System.out.println(bo3 == bo4);  //true
    System.out.println(bo3.equals(bo4));  //true

2.10 源代码分析

2.10.1 系统重写equals()方法

Integer的equals()系统重写后的源代码

1| public boolean equals(Object obj) {
2|        if (obj instanceof Integer) {
3|            return value == ((Integer)obj).intValue(); // 将包装类拆成基本数据类型比较
4|        }
5|        return false;
6|    }
2.10.2 value源码
public Integer(int value) {
        this.value = value;
    }
2.10.3 valueOf源码
Integer的valueOf():源码

Byte,Short,Integer,Long缓存都是一样,[-128,127]

 public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)  //[-128,127]
        //IntegerCache.low 缓存池里面定义了静态常量为-128
            return IntegerCache.cache[i + (-IntegerCache.low)];   //溢出计算,得到的对应索引
        return new Integer(i);    //返回cache数组的一个值,否则new一个新的Integer对象
    }
Double的ValueOf():源码

Double,Float无缓存,直接构造对象
原因: Double和Float之所以不用缓存,是因为没有办法缓存,(0,1)这么小的一个区间里面,就有无数个double或float数,根本无从缓存。所以在使用Double和Float自动装箱时,全都是构造新的对象,没有缓存。

  public static Double valueOf(Double d) {  
        return new Double(d);  
    }  
Boolean的ValueOf():源码

只要不new,和比较的boolean值不同,就返回true

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);

     public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
Character的ValueOf():源码
    public static Character valueOf(char c) {
        if (c <= 127) { // must cache[0-127]
            return CharacterCache.cache[(int)c];
            //将返回CharacterCache.cache[(int)c],返回事先缓存的内容
        }
        return new Character(c);
    }

2.11 自动装箱范围源代码缓存

Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),这相当于调用 valueOf 方法

2.11.1 Integer缓存池
private static class IntegerCache {
static final int low = -128;
static final int high;   //127可以更改
static final Integer[] cache;  //从[low,high]所对应的Integer对象,长度是high-low+1(因为有元素0,所以要加1)
static Integer[] archivedCache;

static {
    // high value may be configured by property
    int h = 127; 
    String integerCacheHighPropValue =
        VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    if (integerCacheHighPropValue != null) {
        try {
            h = Math.max(parseInt(integerCacheHighPropValue), 127);
            // Maximum array size is Integer.MAX_VALUE(最大数组大小是整数)
            // public static final int MAX_VALUE = 0x7fffffff;//2147483647对应的16进制数
            h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
            //high 默认是127,可以改变,最大不超过:Integer.MAX_VALUE - (-low) -1
        } catch( NumberFormatException nfe) {
            // If the property cannot be parsed into an int, ignore it.(如果无法将属性解析为int,请忽略它。)
        }
    }
    high = h;   //  high=127

    // Load IntegerCache.archivedCache from archive, if possible(从存档加载整数缓存存档缓存池中)
    VM.initializeFromArchive(IntegerCache.class);
    int size = (high - low) + 1;

    // Use the archived cache if it exists and is large enough(使用存档缓存,如果存在并且足够大)
    if (archivedCache == null || size > archivedCache.length) {
        Integer[] c = new Integer[size];
        int j = low;
        for(int i = 0; i < c.length; i++) {
            c[i] = new Integer(j++);
        }
        archivedCache = c;
    }
    cache = archivedCache;
    // range [-128, 127] must be interned (JLS7 5.1.7)(范围[-128,127],)
    assert IntegerCache.high >= 127;
}

private IntegerCache() {}
}
2.11.2 Character缓存池
private static class CharacterCache {
    private CharacterCache(){}

    static final Character[] cache;
    static Character[] archivedCache;

    static {
        int size = 127 + 1;//+1 [1-128],没有0

        // Load and use the archived cache if it exists
        VM.initializeFromArchive(CharacterCache.class);
        if (archivedCache == null || archivedCache.length != size) {
            Character[] c = new Character[size];
            for (int i = 0; i < size; i++) {
                c[i] = new Character((char) i);
            }
            archivedCache = c;
        }
        cache = archivedCache;
    }
}

2.12 分析

1.instanceof: 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例
2.obj: 传入的必须是引用数据类型,obj为null的时候返回false,null 是可以成为任意引用类型的特殊符号
3.Integer: Integer可以是接口或者类和子类
4.null: 返回false,null 是可以成为任意引用类型的特殊符号。
5.intValue(): 把Integer对象的类型变成int基本数据类型,java.lang.Number类的方法,Number是一个抽象类
6.indexOf():把给定的String参数转化成Integer对象类型
7.parseInt():把String变成int基本数据类型,按十进制进行转换
8.源码三,四:从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。 上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。
Double和Float,比较值==比较
注意: Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。Double、Float的valueOf方法的实现是类似的。可以看下他们的缓存池(IntegerCache),明白其原理

2.13 例题

1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)

    Integer a = 1;
    Integer b = 2;
    Integer c = 3;
    Integer d = 3;
    Integer e = 321;
    Integer f = 321;
    Long g = 3L;
    Long h = 2L;

    System.out.println(c==d); //true [-128,127]之间,值一样地址就一样
    System.out.println(e==f);  //false
    System.out.println(c==(a+b));   //true a+b是算术运算符,会触发自动装箱
    System.out.println(c.equals(a+b));   //true  
    //先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较
    System.out.println(g==(a+b));  //true
    System.out.println(g.equals(a+b));   //true.equals(false) false
    /*源码
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }
    */
    System.out.println(g.equals(a+h));   // a+h == long -- > true
    //如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法

3. Math类

3.1 概述

Math类包含三角函数方法,指数函数方法,服务方法

3.2 静态属性

PI 比任何其他值都更接近 pi(即圆的周长与直径之比)的 double 值。3.141592653589793
E 比任何其他值都更接近 e(即自然对数的底数)的 double 值。 2.718281828459045

3.3 三角函数方法

方法描述
sin(radians)返回以弧度为单位的角度的三角正弦函数值
cos(radians)返回以弧度为单位的角度的三角余弦函数值
tan(Radians)返回以弧度为单位的角度的三角正切函数值
toRadians(degree)将以度为单位的角度值转换为以弧度表示
toDegrees(radians)将以弧度为单位的角度值转换为以度表示
sain(a)返回以弧度为单位的角度的反三角正弦函数值
acos(a)返回以弧度为单位的角度的反三角余弦函数值
atan(a)返回以弧度为单位的角度的反三角正切函数值

cos,sian,tan都是以弧度为单位的角度
asin,atan的返回值是-π/2 ~ π/2的一个弧度值,acos的返回值在0 - π之间. 1°相当于π/180弧度,90°相当于π/2弧度
Math.cos(60 * Math.PI/180);把60转换为60°

3.4 Math指数函数

方法描述
exp(x)返回e的x次方
long(x)返回x的自然对数(lnx = long e的X次方)
long10(x)返回X的以10为底的对数(long 10次方)
pow(a,b)返回a的b次方
sqrt(x)对于x≥的数字,返回x的平方根
abs(x)返回X的绝对值
max(a,b)返回两个数的最大值
min(a,b)返回两个数的最小值

3.5 取整方法

方法描述
ceil(x)x向上取整为它最接近的整数.该整数作为一个双精度值返回
floor(x)X向下取整为它最接近的整数.该整数作为一个双精度值返回
rint(x)x取整为它最接近的整数,如果x与两个整数距离相等,偶数整数作为双精度值返回
round(x)四舍五入
random()随机产生[0,1)之间的数的double的数
  1. (int)(Math.random() * 10) --> 生成0~9之间的随机数
  2. 50 + (int)(Math,random() *10) – > 生成50-60之间的随机数
  3. (int)((int)‘a’ + Math.random() * (int)‘z’ - (int)‘a’ + 1) 随机生成a-z之间的数
  4. (char)(‘a’ + Math.random() * (‘z’ - ‘a’ + 1)) 随机生成’a’ - 'z’之间的随机小写字母
  5. a + (int)(Math.random + b) --> 生成[a,b)之间的随机数

4. Arrays类

JDK提供的java.util.Arrays类,包含常用的数组操作方法有:排序,查找,填充,打印等内容

4.1 toString方法

以字符串的形式返回数组内容

public static void main(String[] args) {
		int[] a = new int[3];//声明数组
		System.out.println("a数组的地址: "+ a);//a数组的地址:[I@279f2327
		a[0] = 12;//数组赋值
		a[1] = 13;
		a[2] = 14;
		System.out.println(Arrays.toString(a));//[12, 13, 14]
	}

注意和Object的toString方法不同,是两种不同的方法

//Object的toString源码
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

//Arrays的toString的源码,是静态的
public static String toString(int[] a) {
        if (a == null) //传递的数组为空,返回null字符串
            return "null";
        int iMax = a.length - 1;//数组的最大索引值
        if (iMax == -1)//最大索引值不等于-1,否则返回[]
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');//先添加[
        for (int i = 0; ; i++) {
            b.append(a[i]);//向[a,b,c,d,e
            if (i == iMax)//遍历完数组长度为0后-1,就会返回[a,b,c,d,e]
                return b.append(']').toString();
            b.append(", ");
        }
    }

4.2 sort,parallelSort与Comparable

sort与parallelSort可以对数组和部分数组排序

对数组排序: Arrays.sort(arr, fromIndex, toIndex);
对部分数组排序: Arrays.parallelSort(arr, fromIndex, toIndex);//[fromIndex, toIndex)

这两个方法基本没有什么区别,如果电脑是有多个处理器,用 parallelSort 更加高效

public static void main(String[] args) {
		int[] a = {2,5,9,32,5,2,1};
		System.out.println(Arrays.toString(a));//[2, 5, 9, 32, 5, 2, 1]
		//Arrays.sort(a);
        Arrays.parallelSort(a);
		System.out.println(Arrays.toString(a));//[1, 2, 2, 5, 5, 9, 32]
	}

数组引用类型排序(容器):需要继承Comparable接口,重写CompareTo

public class Test {
    public static void main(String[] args) {
        Man[] msMans = { new Man(3, "a"), new Man(60, "b"), new Man(2, "c") };
        Arrays.sort(msMans);
        System.out.println(Arrays.toString(msMans));
    }
}
 
class Man implements Comparable {
    int age;
    int id;
    String name;
 
    public Man(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }
 
    public String toString() {
        return this.name;
    }
 
    public int compareTo(Object o) {
        Man man = (Man) o;
        if (this.age < man.age) {
            return -1;
        }
        if (this.age > man.age) {
            return 1;
        }
        return 0;
    }
}

4.3 二分法查找

public static void main(String[] args) {
		int[] a = {2,5,9,32,5,2,1};
		Arrays.sort(a);//使用二分法查找必须先对数组排序
		System.out.println(Arrays.toString(a));//[1, 2, 2, 5, 5, 9, 32]
		System.out.println(Arrays.binarySearch(a, 2));//查找a = index(1) ,返回第一个a的索引,未找到返回负数
	}

4.3 数组内存分析

4.3.1 一维数组

一维数组创建时大小就是固定的,数组是传址,不传值

int[] a = {2,3,5,9,32};
//一个数组变量看似存储一个数组,但实际上他指向数组的引用

在这里插入图片描述

4.3.2 二维数组

int[][] a = new int[5][5];//图a
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;

int[][] b = {//图b,静态初始化二维数组
    {5,56,3,45,5},
    {7,7,6,12,0},
    {8,5,87,87,6},
    {13,3,45,12,0},
    {34,7,23,2,9}
};

int[][] arr = {//图c,不规则数组
    {1,2,3,4,5},
    {1,2,3,4},
    {1,2,3},
    {1,2},
    {1}
}

在这里插入图片描述

4. Random类

4.1 概述

产生随机数,如果相同的种子创建两个Random实例,则对每个实例进行相同方法的调用序列,生成并返回相同的数字序列

4.2 构造方法

public Random()
public Random(long seed)

4.3 成员方法

Random rand = new Random();

//public double nextDouble() 随机生成[0,1)之间的double类型数据
rand.nextDouble();
//public int nextInt() 随机生成[0,1)之间的int类型数据
rand.nextInt();

// public int nextInt(int bound) 随机生成0 - bound之间的数
rand.nextInt(10);
20 + (int)(rand.nextInt(10)); //随机生成[20,30)
20 + (int)(rand.nextDouble() * 10)

//public float nextFloat() 随机生成[0,1)之间的float类型数据
rand.nextFlaot();

//public boolean nextBoolean() 随机生成true,false
rand.nextBoolean();

5. System类

5.1 概述

系统类,主要用于获取系统的属性数据,没有构造方法
System表示当前运行的JVM,System提供标准输入,输出,错误流对象
对外部定义的属性和环境变量访问
加载文件和库文件;还有快速复制数组的一部分实用方法
获取系统时间和现实告知垃圾回收释放内存的方法
System只读不能实例化

5.2 成员属性

  1. System.out 获取标准输出流
System.out.println("dsjhfj");//标准输出
  1. System.in 获取标准输入流
Scanner sc = new Scanner(System.in); // 获取从键盘中输入
  1. System.err 获取错误输出流
System.err.println("dsjhfj");//红色错误输出,显示的位置是随机的,不会出现在某一个固定地方

5.3 成员方法

1.public static void exit(int status); 退出系统 status:0 正常终止,非0异常终止

System.exit(0); //退出程序

2.public static void gc(); 通知垃圾回收系统期望快速回收垃圾以释放空间

System.gc(); // 调用JVM,期望快点回收

3.public static long currentTimeMillis(); 获取系统当前时间,毫秒表示

System.currentTimeMIllis();//获取1970-1-1 00: 00 :00日到现在的毫秒数

4.public static Properties getProperties(); 获取当前系统属性map集合

    Properties pro = System.getProperties();
    System.out.println(pro);
    输出:
    {sun.desktop=windows, awt.toolkit=sun.awt.windows.WToolkit, java.specification.version=12, sun.cpu.isalist=amd64, sun.jnu.encoding=GBK,....

= 号左右为一对键值对,逗号分隔
查看jdk版本号 System.out.println(System.getProperty(“java.specification.version”)); // 12

5.public static String getProperty(String key); 按照给定的名称获取当前系统属性字符串表示

    System.out.println(System.getProperty("java.specification.version")); // 查看jdk版本号 12

6.public static void arrcopy(Object src, int srcPos,Objext dest,int destPos,int length) //复制的数组 ,开始索引,目标数组,目标数组desPos索引开始,复制长度

    int [] a12 = {1,2,3,4,5};
    int [] a13 = new int[5];
    System.arraycopy(a12, 1, a13, 3, 2);//(a13,
    for(int i = 0; i < a13.length; i++) {
        System.out.print(a13[i] + " ");
        //0 0 0 2 3
    }

6. BegInteger类

6.1 概述

可以让超过Integer范围内的数据进行计算,大数字计算

6.2 构造方法

public BigInteger(String str)

6.3 成员方法

    BigInteger big01 = new BigInteger("10");
    BigInteger big02 = new BigInteger("3");
        //public BigInteger add(BigInteger val)   加
    BigInteger bigAdd = big01.add(big02);  //13

        //public BigInteger subtract(BigInteger val) 减
    BigInteger bigSubtract = big01.subtract(big02); // 7

        //public BigInteger multiply(BigInteger val) 乘
    BigInteger bigMultiply = big01.multiply(big02);  //30

        //public BigInteger divide(BigInteger val) 除
    BigInteger bigdivide = big01.divide(big02);  //3

        //public BigInteger[] divideAndRemainder(BigInteger val) 取模
    BigInteger[] bigDiv = big01.divideAndRemainder(big02); //商: bigDiv[0] = 3; 余: bigDiv[1] = 1
    System.out.println(bigAdd + "  " + bigSubtract + "  " + bigMultiply+"  " + bigdivide + "  ");
    for(int i = 0; i < bigDiv.length;i++) {
        System.out.print(bigDiv[i] + "  ");
    }

7. BigDecimal类

7.1 概述

由于在运算的时候,float类型和double类型很容易丢失精度,所以,为了能够精确地表示,计算浮点数,java提供了BigDecimal

7.2 构造方法

public BigDecimal(String augend)

7.3 成员方法

double a = 1;
double b = 0.9;
System.out.println(a-b);//0.09999999999999998

BigDecimal de01 = new BigDecimal("1");
BigDecimal de02 = new BigDecimal("0.9");
//public BigDecimal add(BigDecimal augend)
System.out.println(de01.add(de02));   //1.9

//public BigDecimal subtract(BigDecimal augend)
System.out.println(de01.subtract(de02));//0.1

//public BigDecimal multiply(BigDecimal augend)
System.out.println(de01.multiply(de02));//0.9

//public BigDecimal divide(BigDecimal augend)
System.out.println(de01.divide(de02));  //除不尽 java.lang.ArithmeticException

8. Date类

8.1 概述

Date类表示特定的时间,精确到毫秒数

8.2 构造方法

public Date()
public Date(long date)

8.3 成员方法

Date date = new Date();//Wed Oct 09 16:31:11 CST 2019
System.out.println(date); //星期 月份 日 小时:分钟:秒 时区 年

// public long getTmie()   //获取时间
//自1970年1月1日 00:00:00 到现在的时间的毫秒数
long time01 = date.getTime();
long time02 = System.currentTimeMillis();
System.out.println(time01 + "    " + time02);//1570610157580    1570610157636

//把毫秒转换成现在的日期
Date date03 = new Date(time01);
System.out.println(date); //Wed Oct 09 16:35:57 CST 2019

// public void setTime(long time)   //设置时间
Date date04 = new Date();
date04.setTime(time01); // 设置时间,传入值
System.out.println(date04);//Wed Oct 09 16:35:57 CST 2019

9. SimpleDateFormat类

9.1 概述

DateFormat是日期/时间格式化子类的抽象类,用于格式化并解析日期和时间,他是一个抽象类,所以使用其子类SimpleDateFormat

9.2 构造方法

public SimpleDateFormat()
public SimpleDateFormat(String pattern)

9.3 成员方法

public final String format(Date date)
public Date parse(String source)
//获取当前时间
Date date = new Date();
System.out.println(date); //Wed Oct 09 16:53:35 CST 2019

//把Wed Oct 09 16:53:35 CST 2019 --> 2019年10月9日 16:53:35

//创建一个"日期格式化字符串"
//DateFormat sdf01 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//多态写法
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss z Z");
//yyyy年MM月dd日  yyyy-MM-dd  yyyy/MM/dd

//1. date  -- > String

//把Date类型转成固定格式字符串
String str = sdf.format(date);
System.out.println(str); //2019年10月09日 16:57:33


//2. String --> date

String str01 = "2019年10月9日 16:53:35";
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");//格式和str01里面的字符串格式一样

//如果不用try...each(ParseException)...,可以在main方法后面加throws ParseException //把异常抛出去
try {
    Date date01 = df.parse(str01);
    System.out.println(date01);
    //解析str01的内容成date格式,如果格式不一样就会报解析异常java.text.PaeseException
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();  //红色字输出
}

9.3 时间日期模式

字母日期或者时间元素表示示例
GEra标志符TextAD
yYear1996;96
M年中的的月份YearJuly;Jul;07
w年中的周数NUmber27
W月份中的周数Number2
D年中的天数Number189
d月份中的天数Number10
F月份中的星期Number2
E星期中的天数TextTuesday; Tue
aAm/pm标记TextPM
H一天中的小时数(0-23)Number5
k一天中的小时数(1-24)Number24
Kam/pm中的小时数(0-11)Number0
ham/pm中的小时数(1-12)Number12
m小时中的分钟数Number30
s分钟中的秒数Number55
S毫秒数Number978
z时区General time zoneCST
Z时区PFC 822 time zone+0800

10. Calendar类

10.1 概述

Calendar类:一个抽象类,他为特定瞬间一组诸如YEAR,MONTH,DAY_OF_MONTH,HOUR等日历字段之间的转换提供的方法,并为操作日历字段(例如获取下个星期的日期)提供了一些方法

10.2 成员方法

public static Calendar getInstance()
public int get(int field)

10.3 结构

  • Object
    • Galendar
      • GregorianCalendar 公历
      • JapaneselmperialCalendar 小日本用的日历

注意: 获取月份时0:1月;1:2月,2:3月,…,11:12月 ; 获取星期时1: 周日,2: 周一,3: 周二,…,7周六

10.4 日历字段组合

日期字段

YEAR + MONTH + DAY_OF_MONTH 年,月,日组合
YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 年,月,这个月第几周,星期几
YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 年,月,当月第几个星期,星期几
YEAR + DAY_OF_YEAR 年,当年中的天数
YEAR + DAY_OF_WEEK + WEEK_OF_YEAR 年,一个星期中的某天,当前年中的星期数

时间字段

HOUR_OF_DAY 指示上午或下午的小时。
AM_PM + HOUR 从午夜到中午之前这段时间的 AM_PM 字段值

10.5 get(),set(),add()

//Calendar是抽象类, 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化
Calendar calendar = Calendar.getInstance();
//公历  不用这种
//Calendar calendar01 = new GregorianCalendar();

//get()获取日历相关元素
System.out.println("年 " + calendar.get(Calendar.YEAR));  //获取年
System.out.println("月 " + calendar.get(Calendar.MONDAY))+1; //获取月 0-> 1月
System.out.println("日 " + calendar.get(Calendar.DATE//DAY_OF_MONTH));//获取日
System.out.println("星期 "+ calendar.get(Calendar.DAY_OF_WEEK));//一个月中第几个星期[1-6][日,六]
System.out.println(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));//当前月的第几个星期
System.out.println("时 " + calendar.get(Calendar.HOUR));//获取小时
System.out.println("分 " + calendar.get(Calendar.MINUTE));//获取分钟
System.out.println("秒 " + calendar.get(Calendar.SECOND));//获取秒
System.out.println("毫秒: " + calendar.get(Calendar.MILLISECOND));//获取毫秒

//set()设置日期相关元素
Calendar calendar01 = Calendar.getInstance();
calendar01.set(Calendar.YEAR, 3000);//field日期元素,value那个
//计算日历
calendar02.add(Calendar.YEAR, 100);//往后100年
System.out.println(calendar02.get(Calendar.YEAR));

10.6 时间和日期之间的转化

Calendar calendar04 = Calendar.getInstance();
Date date = calendar04.getTime(); //把日期类转成时间对象
Calendar calendar05 = Calendar.getInstance();
calendar05.setTime(date);//把时间对象转成日期类

10.7 格式化日历

用户输入一个日期,格式(2010-10-10),10号这天后面加星号

// 1.输入字符串时间,格式要一致
Scanner sc = new Scanner(System.in);
System.out.print("请输入日期(格式为:2019-10-10): ");
String str = sc.nextLine();
// 2.把字符串类型转换为Date格式
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 3.解析格式
Date date01 = null;
//抛出异常
try {
    date01 = df.parse(str);
    // 解析str01的内容成date格式,如果格式不一样就会报解析异常java.text.PaeseException
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace(); // 红色字输出
}
// 打印头部
System.out.printf("%-6s%-6s%-6s%-6s%-6s%-6s%s\n", '日', '一', '二', '三', '四', '五', '六');
// 创建Calendar对象
Calendar calendar = Calendar.getInstance();
//日期格式改成时间格式
calendar.setTime(date01);
//获取用户输入输入的天数
int day = calendar.get(Calendar.DATE);
//设置用户输入这个月全部为1号
calendar.set(Calendar.DATE, 1);
//1号星期前面补充空格
for(int i = 0; i < calendar.get(Calendar.DAY_OF_WEEK)-1;i++) {
    System.out.printf("%-4s","  ");
}
//获取本月的最大天数,days不能放入for循环中,30天会有bug,全天30天会多接受一个数
int days = calendar.getActualMaximum(Calendar.DATE);
for(int i = 1;i <= days;i++) {
    //判断遍历的日期是否等于输入的日期,是在后面的数字打上"*"
    if(calendar.get(Calendar.DAY_OF_MONTH) == day) {
        System.out.printf("%-4s", calendar.get(Calendar.DAY_OF_MONTH)+"*");
    }else {
        System.out.printf("%-4d", calendar.get(Calendar.DAY_OF_MONTH));
    }
    //获取每天的星期,如果是星期六,就换行
    if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
        System.out.println();
    }
    //开始设置全是1,每循环一次加一,知道本月最大
    calendar.add(Calendar.DAY_OF_MONTH, 1);
}

11. String类

11.1 概述

String类对象代表不可变的Unicode字符序列,可以将String成为"不可变对象",如下:源码
字符和字符串是两种不同类型,字符是基本数据类型,字符串是引用数据类型,String的引用值存在常量池中

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence,
               Constable, ConstantDesc {

    private final byte[] value;
    //字符串里面的内容全部存到value[]数组中,而value被final修饰,也就是常量(只能赋值一次),没有子类继承
String str1 = "hello " + "world";
String str2 = "hello world";
// == 比较的是内存的对象,String内部优化将字符串进行拼接,常量一样内存指向同一个地址
System.out.println(str1 == str2);  //true
System.out.println(str1.equals(str2));  //true

String str3 = "hello ";
String str4 = "java";
//编译器的时候不知道变量里面存的是什么,没有办法在编译的时候拼接,只能开辟新空间
String str5 = str3 + str4;
System.out.println(str3 == str4);  //false
System.out.println(str3.equals(str4));  //false

11.2 字符串内存

字符串是引用数据类型,字符是基本数据类型,字符串是不可变的

public static void main(String[] args) {
    String a = "Hello"; //内存中a变量指向内存0x11空间
    a = "Hi"; //然后a变量指向了0x12
    System.out.println(a);
    //jvm虚拟机会先创建字符串hello,然后把字符串指向"Hi"空间,原来的"Hello"还在内存中,只是我们现在无法访问,因此字符串是不可变的字符串内容
}

在这里插入图片描述

11.3 字符串的null与""

public static void main(String[] args) {
String s1 = null;//a是空
String s2;//没有初始化赋值也是null
String s3 = s1;//s3也是空
String s4 = “”;//s4指向空串,不是null
}

空串不等于null;在字符串中加号是拼接字符串

11.4字符数组创建字符串

char[] cha = {'a','b','c','d','e','d','b'};
String str01 = new String(cha); //把字符转成字符串==String str = new String("abcde")
System.out.println("打印str01字符串: "+str01);

11.5 截取字符串

substring(int beginIndex),从beginIndex位置开始截取至最后面
substring(int beginIndex,int endIndex);从beginIndex开始至endIndex的地方结束

char[] cha = {'a','b','c','d','e','d','b'};
//1 获取字符串
String str02 = new String(cha,2,3);//从索引为2的位置开始截取,后面3个数
System.out.println("打印str02字符串: " + str02);
//2获取字符串:substring()可以对字符串进行截取,利用索引进行截取,区间[begin , end)
//substring(int beginIndex),从beginIndex位置开始截取至最后面
System.out.println("substring指定开始位置: " + str01.substring(3));//输出:dedb
//3 substring(int beginIndex,int endIndex);从beginIndex开始至endIndex的地方结束
System.out.println("substring指定开始-结束位置: " + str01.substring(1,3));//输出:bc

11.6 获取字符串长度

public int length();

System.out.println("打印Str02的长度: " + str02.length());//输出3

11.7 字符串的查找

11.7.1 indexof()

3.如果字符串为空串("“非空格),输出0
4.如果指定为空(”"非空格)输出为fromindex

public int indexOf(String str)
public int indexOf(String str,int fromindex);从[fromindex,leng-1],从fromindex向后开始查找

String str01 = new String("abcdedb");
System.out.println("indexof 非指定: " + str01.indexOf("b")); //输出:1
//从0索引向后数,返回第一次出现的位置的索引
System.out.println("indexof 非指定空: " + str01.indexOf(""));  //输出:0
//索引没有找到的值返回0
System.out.println("indexof 指定: " + str01.indexOf("b",2));//输出6
//从索引为2的地方开始向后找,返回找到的索引,没有找到就返回,从开始那个地方开始查找的索引
System.out.println("indexof 指定: " + str01.indexOf("",4)); //输出3
11.7.2 lastIndexOf()

1.方法返回的是搜索的字符串或字符最后一次出现的位置
2.没找到返回-1
3.如果字符串里面是空串(没有空格""),返回结果是该字符调用length()方法返回值一样
4.如果指定为空(""非空格)输出为fromindex

public int lastIndexOf(String str)
public int lastIndexOf(String str,int fromindex);从[0,fromindex]前后开始查找,返回最后一次出现的位置

String str01 = "abcbdedbfa";
System.out.println("lastIndexOf非指定: " + str01.lastIndexOf("a")); //输出9
//从前向后看,返回最后出现的a的索引
System.out.println("lastIndexOf非指定空: " + str01.lastIndexOf("")); //输出10
//搜索为空,返回字符串的长度,与index搜索相反
System.out.println("lastIndexOf指定: " + str01.lastIndexOf("b",5));  //输出3
//索引为[0,5]的位置查找,从0索引开始看,返回最后一次出现的索引,前面没有返回-1
System.out.println("lastIndexOf指定: " + str01.lastIndexOf("",5)); //输出5
//指定字符串为空(""非空格),fromindex为几就返回几,与indexOf一样

11.8 去除空格

public String trim(); //去除前后空格,中间的不去除,返回副本

String a = " Hello world ! ! !  ";
System.out.println("去除前后空格:" + a.trim());//去除前后空格:Hello world ! ! !

注:字符串的替换也可以去空格

11.9 字符串的替换

1.public String replace(target(目标),replacement(更换))
2.public String replaceALL(regex(正则表达式),replacement(更换))
3.public String replaceFirst(regex(正则表达式),replacement)

//6.1 public String replace(target,replacement);  
System.out.println("字符串替换replace: " + a.replace(" ",""));  //Helloworld!!!  去除所有的空格,包括首尾,中间
//6.2 pulic String replaceAll(regex,replacement); //去除所有的空格,包括首尾,中间
System.out.println("字符串替换replaceAll: " + a.replaceAll(" ",""));  //Helloworld!!!
System.out.println("字符串替换replaceAll正则表达式1: " + a.replaceAll(" +",""));  //Helloworld!!!
System.out.println("字符串替换replaceAll正则表达式2: " + a.replaceAll("\\s*",""));  //Helloworld!!!
//6.3 public static replaceFirst()   //第一个出现字符替换
System.out.println("字符串替换replaceFirst" + a.replaceFirst("\\s*","")); //Hello world ! ! !

11.10 判断字符串的开始与结尾

public boolean startsWith(String prefix)方法判断当前字符串对象的前缀是否以指定的内容开始
public boolean endsWith(String suffix)方法判断当前字符串对象的前缀是否以指定的内容开始

String b = "22115151";
//7.1 public boolean staetsWith(String prefix);
System.out.println("判断字符串是否以22开头" + b.startsWith("22"));  //true
System.out.println("判断字符串是否以32开头" + b.startsWith("32"));  //false
//7.2 public boolean endsWith(String suffix)
System.out.println("判断字符串是否以51结尾" + b.endsWith("51"));  //true
System.out.println("判断字符串是否以15结尾" + b.endsWith("15"));  //false

11.11 字符串比较

1 == 默认比较的是地址
2 public boolean equals equals(String other) 默认比较内容,区分大小写
3 public boolean equals equalsIgnoreCase(String other) 默认比较内容,不区分大小写
4 public int equals compareTo(String other) 按照字典的顺序比较两个字符串,该比较基于字符串中各个字符的unicode值

4.1 String对象在参数other前面,返回-1 string(小) - other(大) = 0
4.2 String对象在参数other后面,返回1 string(大) - other(小) = 1
4.3String对象和参数other相等,返回0 string(=) - other(=) = 0
4.4String对象和参数other除去大小写一样,返回32或者-32 例:8.4

String c1 = "abc";
String c2 = "abc";
String c3 = "ABC";
String c4 = new String("abc");
String c5 = new String("abc");
String c6 = new String("ABC");
String c7 = new String("bcd");
String c8 = new String("Abc");
System.out.println("字符串c1,c2 == 比较" + (c1 == c2));   //true
//8.2 public boolean equals(String other);
System.out.println("字符串c1,c2 equals 比较" + c1.equals(c2));  //true
System.out.println("c1的地址值" + c1.hashCode());  //96354
System.out.println("c2的地址值" + c2.hashCode());  //96354
System.out.println("字符串c3,c4 == 比较" + (c3 == c4));  //false
System.out.println("字符串c3,c4 equals 比较" + c3.equals(c4));  //true
//8.3 public boolean equalsIgnoreCase(String other);
System.out.println("字符串c2,c3 equalsIgnoreCase 比较" + c2.equalsIgnoreCase(c3));  //true
System.out.println("字符串c4,c5 equalsIgnoreCase 比较" + c4.equalsIgnoreCase(c5));  //true
System.out.println("字符串c2,c6 equalsIgnoreCase 比较" + c2.equalsIgnoreCase(c6));  //true
//8.4 public int compareTo(String other);
System.out.println("字符串c5,c7 compareTo比较"+ c5.compareTo(c7));  //-1
System.out.println("字符串c5,c6 compareTo比较"+ c5.compareTo(c6));  //32,反过来-32
System.out.println("字符串c5,c6 compareTo比较"+ c6.compareTo(c8));  //-32

11.12 字母大小写转换

1 toLowerCase()将String转为小写,如果字符串中没有该字符,将返回原来字符,否则返回新字符串,只限字母受影响,不返回副本,直接修改
2 toUpperCase()将String转为大写,如果字符串中没有该字符,将返回原来字符,否则返回新字符串,只限字母受影响,不返回副本,直接修改

String d1 = new String("123aBcd%_cd");
//9.1 public String toLowerCase();
System.out.println("字符串d1转为小写:" + d1.toLowerCase()); //输出: 123abcd%_cd
//9.2 public String toUpperCase();
System.out.println("字符串d1转为大写:" + d1.toUpperCase()); //输出: 123ABCD%_CD

11.13 字符串分割

1 split(String sign) //给定分割符分割,也可以是正则表达式,分割完存放到字符数组里面
2 split(String sign,int limit) //给定分割符分割,并限定分割的次数,分割完存放到字符数组里面

String d2 = new String("192.168.3.1");
//10.2 public String[] split(String sign)
String[] d3 = d2.split("\\.");
for(int i = 0; i < d3.length; i++){
    System.out.print("[" + d3[i] + "]");   //[192][168][3][1]
}
System.out.println();
//10.2 public String[] split(String sign,int limit)
String[] d4 = d2.split("\\.",2);
for(int i = 0; i < d4.length; i++){
    System.out.print("[" + d4[i] + "]");   //[192][168.3.1]
}
System.out.println();

11.14 格式化字符串

11.14.1 format格式化

1 format() 给定特殊的转换符作为参数来实现对日期和时间的格式化

1.1 public static String format(String format,Object…args) 制定字符串格式和参数生成格式化的新字符串,新字符串使用本地环境,输出println
1.2 public static String format(Local l,String format,Object…args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串,输出printf

1.2.1.Local: 格式化过程中要应用语言环境,如果1为null,则不进行本地化 %n换行
1.2.2 format: 格式化字符串,和C语言打印的字符格式是一样
1.2.3 args:格式化字符串中由格式说明符引用的参数.如果还有一个说明符以外的参数,则忽略这些额外的参数.由此参数数目是可变的,可以为0

//public static String format(String format, Object... args)
String str = String.format("Hi,%s,%s,%s","王莉","张三","李四");
System.out.println("format方法" + str); //Hi,王莉,张三,李四
//public static String format(Local l,String format, Object... args)
System.out.printf("字母a的大写是:%c %n", 'A');  //A
System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);  //42.5000
Date date01= new Date();
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date01);  //10:20:50 下午  %tr见下面时间说明
11.14.2 日期字符串格式化
转换符说明
%ta指定语言环境的星期几简称Mon(英文),星期一(中文)
%tA指定语言环境的星期几全称Monday(英文),星期一(中文)
%tb指定语言环境的月份简称Feb(英文),二月(中文)
%tB指定语言环境的月份全称February(英文),二月(中文)
%tc包括全部日期和时间信息星期二 三月 25 13:37:22 CST 2008
%td一月中的第几天(01-31)28
%te一个月中的某一天(1-31)2
%tY4位年份2008
%ty2位年份08
%tj一年中的第几天(001-336)085
%tm月份03
Date date02 = new Date();
String time = String.format("%tY年%tB%td日",date02,date02,date02);
System.out.printf("今年是: %tY年%tm月%td日%n",date02,date02,date02);  //2019年09月05日
System.out.println("今年是: " + time);   //2019年九月05日
11.14.3 时间格式化
转换符说明
%tH2位小数的24时的小时(00-23)14
%tI2位小数的12时制的小时(01-12)05
%tk2位小数的24时的小时(0-23)5
%tl2位小数的12时制的小时(1-12)5
%tM2位数字的分钟(0-59)05
%tS2位小数的秒数(0-60)12
%tL3位小数的毫秒数(000-999)920
%tN9位数字的微秒数(000000000-999999999)062000000
%tp指定语言环境下 上午或下午标记下午(中文),pm(英文)
%tz相对于GMT RFC 82格式的数字时区偏移量+0800
%tZ时区缩写形式的字符串CST
%ts1970-01-01 00:00:00至现在经过的秒数1206426646
%tQ1970-01-01 00:00:00至现在经过的毫秒数1231512316532
Date date03 = new Date();
String time03 = String.format("%tH时%tM分%tS秒%tL毫秒",date03,date03,date03,date03);
System.out.println("现在的时间:" + time03);  //10时14分19秒670毫秒
System.out.printf("现在的时间:%tH时%tM分%tS秒%tL毫秒%n",date03,date03,date03,date03);
11.14.4 日期时间组合
转换符说明
%tF"年-月-日"格式(4位年份)2008-03-25
%tD"月/日/年"格式(2位年份)03/25/08
%tc“全部日期和时间信息”星期二 三月 25 15:20:00 / CST / 2008
%tr"时:分:秒 PM(AM)"格式(12时制)03:22:06 下午
%tT"时:分:秒"格式(24时制)15:23:50
%tR"时:分"格式(24时制)15:25
Date date04 = new Date();
String time04 = String.format("%tF %tA %tr",date04,date04,date04);
System.out.println("现在的时间: " + time04); //2019-09-05 星期四 10:29:05 上午
System.out.printf("现在的时间: %tF %tA %tr",date04,date04,date04);  //2019-09-05 星期四 10:30:27 上午
11.14.5 常规类型格式化
转换符说明
%b,%B结果被格式化为boolean类型true
%h,%H结果被格式化为散列码A05A5198
%s,%S结果被格式化为字符串类型“abcd”
%c,%C结果被格式化为字符类型‘a’
%d结果为格式化十进制整数40
%o结果被格式化八进制整数11
%x,%x结果被格式化十六进制整数4B2
%e结果被格式化为用计算机科学记数法表示的十进制数1.7000e+01
%a结果被格式化为带有效位数和指数的十六进制浮点值/0X1.C0/00000000001P4
%n结果为特定于平台的行分隔符
%%结果的字面值为’%’%
Date date05 = new Date();
String time05 = String.format("%b",4 >5);
System.out.println("4>5返回的值:"+ time05);  //false
System.out.printf("打印百分比:%d%%%n",25);  //25%

12. StringBuild与StringBuffer

StringBuild: JavaSE5.0新增加的可变字符序列StringBuild类,提高频繁增加字符串的效率,初始容量是16个字符,也可以自行自定长度,想要StringBuilder结果,可以是用toString方法

注: 如果用"+"虽然可以相加,但是会生成新的String实例,内存要开辟新空间,如果重复的修改会浪费大量的系统内存

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    // StringBuilder的父类
    byte[] value;  //String的这个变量被final修饰,这个没有修饰,不可变变量

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuilder>, CharSequence
{//没有被synchronized 修饰,线程不安全 推荐使用
     @Override
    public int compareTo(StringBuilder another) {
        return super.compareTo(another);
    }
    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }
    @Override
    @HotSpotIntrinsicCandidate
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }


 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
{//synchronized  线程安全
@Override
    public synchronized int compareTo(StringBuffer another) {
        return super.compareTo(another);
    }
    @Override
    public synchronized int length() {
        return count;
    }
    @Override
    public synchronized int capacity() {
        return super.capacity();
    }
    ...
12.1 成员方法

public synchronized StringBuffer append(content)方法: 增加字符串,content增加的内容
public synchronized StringBuffer insert(int offset arg): 插入字符串,offset插入的位置,age插入的内容
public synchronized StringBuffer delete(int start,int end): 删除字符串,start删除字符串的起点,end终点
public void setCharAt(int index, char ch): 给出索引,替换ch个索引位
public synchronized StringBuffer reverse(): 倒序输出

StringBuffer的返回值的append返回值类型是StringBuffer
StringBuffer里面的substring()方法.返回值是类型String

// == 比较的是内存的对象,String内部优化将字符串进行拼接,常量一样内存指向同一个地址
//System.out.println(str1 == str2);  //true
//System.out.println(str1.equals(str2));  //true

String str3 = "hello ";
String str4 = "java";
//编译器的时候不知道变量里面存的是什么,没有办法在编译的时候拼接,只能开辟新空间
String str5 = str3 + str4;
//System.out.println(str3 == str4);  //false
//System.out.println(str3.equals(str4));  //false

//线程安全不高,效率高
StringBuilder sb = new StringBuilder("abcdef");
System.out.println(Integer.toHexString(sb.hashCode()));//十六进制无符号字符串: 27716f4
System.out.println(sb.hashCode());//打印sb的哈希码: 27716f4

sb.setCharAt(2, 'C');
System.out.println(Integer.toHexString(sb.hashCode()));//十六进制无符号字符串: 27716f4
System.out.println(sb.hashCode());//打印sb的哈希码: 27716f4

StringBuffer sbf = new StringBuffer();
for(int i = 0; i < 26; i++) {
    char temp = (char)('a' + i);
    sbf.append(temp);
}
System.out.println(sbf);  //abcdefghijklmnopqrstuvwxyz
sbf.reverse();//倒序
System.out.println(sbf);  //zyxwvutsrqponmlkjihgfedcba
sbf.insert(0, '我').insert(3, ' ');//链式调用:return this;自己返回自己
System.out.println(sbf); //我zyxwvutsrqponmlkjihgfedcba
sbf.delete(0, 3);//删除一个区间
System.out.println(sbf);//  xwvutsrqponmlkjihgfedcba

13. 可变字符和不可变字符陷阱

//传统的增加
String str03 = "";  //新建空字符串

long start_num = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间
long startTime = System.currentTimeMillis();//获取系统程序运行前的时间 

for(int i = 0; i < 10000; i++){
    //程序运行中,不断地创建对象(20000个对象)i生成一个对象,连接起来生成一个对象,每次循环都会不断的创建,消耗资源,占用内存
    str03 += i;
}

long endTime = System.currentTimeMillis();//获取系统程序运行后的时间
long end_num = Runtime.getRuntime().freeMemory();//获取系统剩余内存空间

System.out.println("StringBuild类占用多长时间:"+ (endTime - startTime));  //137
System.out.println("StringBuild类占用内存:"+ (start_num - end_num));  //20780824

//12.2 StringBuilder 相加
StringBuilder sb = new StringBuilder("");
start_num = Runtime.getRuntime().freeMemory();
startTime = System.currentTimeMillis();

for(int i = 0; i < 10000; i++){
    sb.append(i);//每次增加i一个对象,然后加入sb里面
}

endTime = System.currentTimeMillis();
end_num = Runtime.getRuntime().freeMemory();
System.out.println("StringBuild类占用多长时间:"+ (endTime - startTime));  //1
System.out.println("StringBuild类占用内存:"+ (start_num - end_num));  //129072

输出:
    StringBuild类占用多长时间:137
    StringBuild类占用内存:20780824
    StringBuild类占用多长时间:1
    StringBuild类占用内存:129072
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值