0
点赞
收藏
分享

微信扫一扫

Java面向对象8-常用类2(Math&String)

Math

1、直接使用,无需导包

package java.lang;

2、final 修饰类 不能被继承

public final class Math

3、构造器私有化,不能创建Math类的对象

private Math() {}

4、Math所有的属性和方法都被static修饰,直接 类名. 调用

5、常用方法

package msb.javase.oop.javase_220310_math;

public class Test {
    public static void main(String[] args) {
        System.out.println(Math.random());
        System.out.println(Math.PI);
        System.out.println(Math.abs(-80));//绝对值
        System.out.println(Math.ceil(9.1));//向上取值
        System.out.println(Math.floor(9.9));//向下取值
        System.out.println(Math.round(3.5));//四舍五入
        System.out.println(Math.max(3, 6));//取大值
        System.out.println(Math.min(3, 6));//取小值
    }
}

6、静态导入

import  static java.lang.Math.*;
System.out.println(random());

存在问题:如果跟Math中的方法重复,那么会优先走本类的自定义方法(就近原则)

package msb.javase.oop.javase_220310_math;

import  static java.lang.Math.*;

public class Test {
    public static void main(String[] args) {
        System.out.println(random()); //100
    }
    public int random(){
        return 100;
    }
}

Random

package msb.javase.oop.javase_220311_random;

import java.util.Random;

public class Test {
    public static void main(String[] args) {
        //学习Random类
        //(1)利用带参数的构造器创建对象(相对用得比较少)
        Random r1 = new Random(System.currentTimeMillis());
        System.out.println(r1.nextInt());
        //(2)利用空参构造器创建对象
        Random r2 = new Random();//表面是在调用无参构造器,底层还是在调用带参构造器
        System.out.println(r2.nextInt(10));
        System.out.println(r2.nextDouble());
    }
}

Math.random()

在这里插入图片描述

String

1、直接使用,无需导包

package java.lang;

2、形象地说一下

* The {@code String} class represents character strings.

在这里插入图片描述

3、所有字符串字面常量都是String的具体 实例/对象

 * All string literals in Java programs, such as {@code "abc"}, are
 * implemented as instances of this class.

4、字符串是不可变的

* Strings are constant; 

5、String类不能有子类,不可以被继承

public final class String

6、字符串底层是一个char类型的数组

private final char value[];

在这里插入图片描述

7、常用方法

(1)Constructor
底层就是给对象底层的value数组进行赋值操作

        String s1 = new String("abc");
        String s2 = new String(new char[]{'a','b','c'});

(2)length、isEmpty、charAt

        //字符串长度
        System.out.println("s1的长度:"+s1.length());//s1的长度:3
        //是否为空
        String s3 = new String();
        System.out.println("s3为空:"+s3.isEmpty());//s3为空:true
        System.out.println("s1为空:"+s1.isEmpty());//s1为空:false
        //charAt
        System.out.println("s1的第3个字符:"+s1.charAt(2));//s1的第3个字符:c

(3)equals(重点)
比较字符串内容,而非比较对象

        String s6 = new String("abc");
        String s7 = new String("edf");
        System.out.println(s6.equals(s7));//false

在这里插入图片描述
(4)compareTo(重点)
String类实现了Comparable接口,里面有一个抽象方法叫compareTo,所以String一定要对这个方法重写
只要字符串不一样,返回非0

        String s8 = new String("abc");
        String s9 = new String("abc");
        System.out.println(s8.compareTo(s9)); //0

在这里插入图片描述
(5)subString、concat、replace、split、toUpperCase、toLowerCase、trim
subString:字符串的截取
concat:字符串的合并/拼接
replace:字符串中字符的替换
split:按照指定的字符串分裂为数组
trim:去除首尾空格

        String s10 = new String("abcdefjk");
        System.out.println(s10.substring(3));//defjk
        System.out.println(s10.substring(2,6));//[3,6)
        System.out.println(s10.concat("bbb"));//abcdefjkbbb
        String s11 = s10.replace("k","c");
        System.out.println(s11);//abcdefjc
        String s12 = new String("a-b-c-d-e-f");
        String[] strs = s12.split("-");
        System.out.println(Arrays.toString(strs));//[a, b, c, d, e, f]

注意此处Arrays.toString的使用

        String s12 = new String("a-b-c-d-e-f");
        System.out.println(s12.toUpperCase());//A-B-C-D-E-F
        System.out.println(s12.toUpperCase().toLowerCase());//a-b-c-d-e-f
        String s13 = new String("   a b c      ");
        System.out.println(s13.trim());//a b c

(6)valueOf:转换为String类型

        System.out.println(String.valueOf(13));//13
        System.out.println(String.valueOf(13.4));//13.4
        System.out.println(String.valueOf(false));//false

8、String的内存分析

(1)字符串拼接
在这里插入图片描述
在这里插入图片描述
内存:
在这里插入图片描述
(2)new关键字创建对象

String s6 = new String("abc");

内存:开辟两个空间(1.字符串常量池中的字符串 2.堆中开辟的对象空间)
在这里插入图片描述
(3)有变量参与的字符串拼接

package msb.javase.oop.javase_220312_string;

public class Test2 {
    public static void main(String[] args) {
        //有变量参与的字符串拼接
        String a = "abc";
        String b = a + "def"; //a变量在编译时不知道a的值是"abc",所以不会进行编译期优化,不会直接合并为"abcdef"
        System.out.println(b);
    }
}

a变量在编译时不知道a的值是"abc",所以不会进行编译期优化,不会直接合并为"abcdef"

反编译(反汇编)过程:为了更好的分析字节码文件是如何进行解析的

  1. 重新编译Build->Recompile ‘Test03.java’
  2. 在out文件夹找到.class字节码文件,重新同步syntho/reload
  3. Terminal:
    cd out/production/testJava/msb/javase/oop/javase_220312_string/
    javap -c Test2.class

在这里插入图片描述
9、可变字符串StringBuilder/StringBuffer

extends AbstractStringBuilder
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;

count:数组有效长度(被使用的长度)

        StringBuilder sb = new StringBuilder();//底层是对value数组进行初始化,且长度为16
        StringBuilder sb2 = new StringBuilder(30);//底层是对value数组进行初始化,指定长度

表面上调用StringBuilder空构造器,实际底层是对value数组进行初始化,且长度固定

    public StringBuilder() {
        super(16);
    }
    public StringBuilder(int capacity) {
        super(capacity);
    }

与上述两种情况不同,传入str的情况下,源码分析:

第一部分

        StringBuilder sb3 = new StringBuilder("abc");
  1. 第一步
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
  1. 第二步
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    public AbstractStringBuilder append(String str) {
        int len = str.length(); //3
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count); //this.value即调用者StringBuilder的value
        count += len;  //count数组被使用的长度,此时为默认值0
        return this;
    }
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) { // 3-19=-16不满足
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { //分别为 0 3 value 0
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); //此处value为调用者str的底层value(字符串"abc"的value)
    }

在这里插入图片描述

第二部分

字符串append

        sb3.append("def");
  1. 第一步
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
  1. 第二步
    public AbstractStringBuilder append(String str) {
        int len = str.length();
        ensureCapacityInternal(count + len); //此时count为3
        str.getChars(0, len, value, count); //"def"调用getChars
        count += len;
        return this;
    }
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) { //3-19
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

在这里插入图片描述

第三部分

空间不够进行扩容

        sb.append("def").append("aaaaaaaa").append("bbb").append("ooooooo");

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) { //24-19>0 空间不够进行扩容
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2; // 19*2 + 2 = 40
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

在这里插入图片描述
7个o赋值到新的长度为40的空间

PS: return this 才可以串连调用

        StringBuilder sb4 =sb3.append("def").append("aaaaaaaa").append("bbb").append("ooooooo"); 
        //return this 才可以串连调用
        System.out.println(sb4);//abcdefdefaaaaaaaabbbooooooo
举报

相关推荐

0 条评论