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"
反编译(反汇编)过程:为了更好的分析字节码文件是如何进行解析的
- 重新编译Build->Recompile ‘Test03.java’
- 在out文件夹找到.class字节码文件,重新同步syntho/reload
- 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");
- 第一步
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
- 第二步
@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");
- 第一步
public StringBuilder append(String str) {
super.append(str);
return this;
}
- 第二步
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