1 String类
特点:
- 内容不可变
- 因为上一点,字符串共享使用,节省内存
- 效果上相当于
char[]
字符数组,但底层原理是byte[]
字节数组
创建方式:
public String()
:初始化新创建的 String对象,以使其表示空字符序列。public String(char[] value)
:通过当前参数中的字符数组来构造新的String。public String(byte[] bytes)
:通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。- 直接创建
String str1 = new String();
char[] charArray = {'A', 'B', 'C'};
String str2 = new String(charArray);
byte[] byteArray = {97, 98, 99};
String str3 = new String(byteArray);
String str4 = "Hello world";
注意:双引号字符串都是 String类对象,直接写上的双引号字符串就在字符串常量池中
字符串的常量池
对于基本类型来说==
是数值的比较,而引用类型是地址值的比较
1.1 常用方法
1.1.1 比较
public boolean equals (Object anObject)
:将此字符串与指定对象进行比较,严格大小写。只有参数是一个字符串,且内容相同才为truepublic boolean equalsIgnoreCase (String anotherString)
:忽略大小写。
String str1 = "Hello";
char[] charArray = {'H', 'e','l','l','o'};
String str3 = new String(charArray);
System.out.println(str1.equals(str3)); //true
推荐"Hello".equls(str1));
推荐此比较方法,(变量在后)不会报错(空指针异常)
1.1.2 获取
public int length ()
:返回长度public String concat (String str)
:将指定的字符串连接到该字符串的末尾。public char charAt (int index)
:返回指定索引处的 char值。public int indexOf (String str)
:返回指定子字符串第一次出现的索引。public String substring (int beginIndex)
:返回一个子字符串,从beginIndex开始截取到结尾。public String substring (int beginIndex, int endIndex)
:返回范围内[ , )子字符串
String str1 = "Hello";
String str2 = "World";
System.out.println(str1.concat(str2)); // "HelloWorld"
charAt 用法
for(int x=0; x<s.length(); x++) {
char ch = s.charAt(x);
}
1.1.3 转换
public char[] toCharArray ()
:将此字符串转换为新的字符数组public byte[] getBytes
() :使用平台的默认字符集将该 String编码转换为新的字节数组,返回的是字节数组对象地址,需要遍历得到此数组public String replace (CharSequence target, CharSequence replacement)
:将与target匹配的字符串使用replacement字符串替换。byte[] --> String[]
:调用String构造器(解码)解码使用的字符集必须与编码时使用的字符集一致,否则乱码char[] --> String
:调用String构造器
String str1 = "Hello";
String str2 = "World";
System.out.println(str1.toCharArray()); // Hello
System.out.println(str1.getBytes()[0]); // 72
System.out.println(str1.replace("H", "h")); // hello
char [] arr = new char[]{"1", "2", "3"}
String str3 = new String(arr)
1.1.4 分割
public String[] split(String regex)
:将此字符串按照给定的regex(规则)拆分为字符串数组。
split的参数是一个正则表达式,所以不能使直接使用.
来做分割符号,应该使用转义字符//.
String str1 = "He,ll,o";
System.out.println(str1); // He,ll,o
String[] array = str1.split(",");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]); // Hello
}
2 StringBuilder类
可变字符序列、效率高、线程不安全
2.1 String类
- String字符串是常量,创建后不能改变
- 字符串底层是final修饰的数组
private final byte[] value
- 进行字符串相加,内存中就会有多个字符串,效率低
String s = "a" + "b" + "c";
a,b,c; ab, c; abc;6个字符串
2.2 StringBuilder类
- 字符缓冲区支持可变的字符串,可提高字符串操作效率(长度可变的字符串)、
- 底层也是一个数组但是没有被final修饰
- 字符串相加时在内存中始终只有一个数组(超出了容量会自动扩容)
2.3 构造方法
public StringBuilder()
:构造一个空的StringBuilder容器。public StringBuilder(String str)
:构造一个StringBuilder容器,并将字符串添加进去。
public static void main(String[] args) {
StringBuilder bu1 = new StringBuilder();
System.out.println(bu1);
StringBuilder bu2 = new StringBuilder("abc");
System.out.println(bu2);
}
2.4 常用方法
public StringBuilder append(...)
:添加任意类型数据的字符串形式,并返回当前对象自身。
StringBuilder bu1 = new StringBuilder();
// append方法返回的是this,调用方法的对象bu1,this=bu1
StringBuilder bu2 = bu1.append("abc"); // 把bu1的的地址赋给了bu2
System.out.println(bu1 == bu2); // 比较的是地址
bu1.append(123);
bu1.append(true);
System.out.println(bu1);
bu2.append("4").append(5).append(false); // 链式编程
System.out.println(bu2);
public String toString()
:将当前StringBuilder对象转换为String对象。
String str = "hello";
StringBuilder bu = new StringBuilder(str);
bu.append(" world");
System.out.println(bu);
String s = bu.toString();
System.out.println(s);
StringBuffer delete(int start,int end)
:删除指定位置的内容StringBuffer replace(int start, int end, String str)
:把[start,end)位置替换为strStringBuffer insert(int offset, xxx)
:在指定位置插入xxxStringBuffer reverse()
:把当前字符序列逆转
3 StringBuffer类
可变字符序列、效率低、线程安全
3.1 常用方法
- public int indexOf(String str)
- public String substring(int start,int end)
- public int length()
- public char charAt(int n )
- public void setCharAt(int n ,char ch)
4 static关键字
以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属于某个对象的。也就是说,既然属于类,就可以不靠创建对象来调用了
4.1 修饰成员和方法
-
没有static关键字的成员变量或方法就必须创建对象才能进行调用
-
有static的既可以通过创建对象调用,也可直接调用
MyClass.methoStatic();
不推荐使用对象obj.methodStatic()
的调用,这样也会被javac翻译成类名.静态方法名()
-
成员方法可以访问静态变量
-
静态方法不能直接访问非静态:因为在内存中是先有的静态内容,后有的非静态内容
-
静态方法中不能用
this
关键字:this代表当前对象,通过谁调用的方法,谁就代表当前对象。但是静态和对象无关,所以不能使用this而应该是类名称.方法名()
public class MyClass {
int num; // 成员变量
static int numStatic; // 静态变量
public void method() {
System.out.println("成员方法");
System.out.println(num);
System.out.println(numStatic);
}
public static void methodStatic() {
System.out.println("静态方法");
System.out.println(numStatic);
// System.out.println(num); // 无法访问
}
}
public class Demo02StaticMethod {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.method();
MyClass.methodStatic();
myMethod(); // == Demo02StaticMethod.myMethod();
}
public static void myMethod() {
System.out.println("自己的方法");
}
}
4.2 静态static的内存图
4.3 静态代码块
格式:
public class ClassName{
static {
// 执行语句
}
}
特点:
第一次用到一个类时,静态代码块只执行唯一的一次
典型用途
用于一次性对静态成员变量复制
public class Person {
static {
System.out.println("执行静态代码块");
}
public Person() {
System.out.println("执行构造方法");
}
}
public class Demo03Static {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
}
}
>>>
执行静态代码块
执行构造方法
执行构造方法