String字符串
创建字符串
java
public class Main {
public static void main(String[] args) {
int[] a={1,2,3};
int[] b=a;
b[0]=99;
System.out.println(a[0]);
String c="hello";
String d=c;
d=d+"!";
System.out.println(c);
System.out.println(d);
}
}
这么写肯定能猜出结果的区别,但是为什么?
因为string对象的内容不可修改。代码执行后会得到一个内容为 "hello!" 的字符串,再让 b 引用它。原来的 "hello" 没有改变,`a` 仍然引用它。
学到这里问了一个问题,答案是:Java支持+=写法,比如a+=10,b+="!"。
比较字符串
比较字符串一般用equals函数。
java
public class Main {
public static void main(String[] args) {
String c="hello";
String d=c;
System.out.println(c==d);
System.out.println(c.equals(d));
d=d+"!";
System.out.println(c.equals(d));
}
}
这个结果是true true false,因为此时c和d引用同一个字符串对象。
但是以下写法会出现false true。
java
public class Main {
public static void main(String[] args) {
String a=new String("hello");
String b=new String("hello");
System.out.println(a==b);
System.out.println(a.equals(b));
}
}
原因:a和b是创建了两个不同的对象。若使用字符串字面量会复用字符串常量池中的对象,也就是String a="hello" String b="hello",这两指代的对象会保持一致。
所以==号是判断是否引用同一个对象,equals只判断字符串值是否相同。
常用函数
注意:字符串方法不会自动保存结果,一定要接收结果。

StringBuilder
可以修改内容的字符串构建工具。
先看这一段:
java
String a="hello";
a=a+"!";
问:原字符串没有改变,s 改为引用拼接结果。的意思是对象本身没有改变,但是s指代的后面加了个!吗?
答:执行第二句时,可以拆成两步理解:
String temp = s + "!"; // 得到内容为 "hello!" 的新字符串
s = temp; // 让 s 引用这个新字符串
原来的 "hello" 对象没有被加上 !
所以如果需要不断追加内容,应该这么写:
java
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
sb.append("!");
System.out.println(sb);
}
}
那么这个对象的字符串操作就和C++学到的很多字符串操作一致了。

例如
java
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
for(int i=0;i<3;i++){
sb.append(i).append("!");
}
System.out.println(sb);
String result = sb.toString();
System.out.println(result);
}
}
问:为什么需要result=sb.toString()?不这么写也能打印出来啊?
答:StringBuilder不是String。String 和 StringBuilder 是两个不同的类,`StringBuilder` 也不是 String 的子类。 它们都能表示文字,但不能直接互相赋值。
StringBuilder是可变对象,所以可以同步修改掉。
java
public class Main {
public static void main(String[] args) {
StringBuilder a=new StringBuilder("Hello c++");
StringBuilder b=a;
b.replace(6, 9, "java");
System.out.println(a);
b.append("!");
System.out.println(a);
}
}
例题
java
public class Main {
public static void main(String[] args) {
StringBuilder a=new StringBuilder("Java");
StringBuilder b=a;
String c=a.toString();
b.append(666);
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
答案也显然是Java666 Java666 Java。
ArrayList
长度可以动态变化的列表。用途接近于C++的vector。
普通数组的创建:int\[\] a=new int3;但是长度固定
ArrayList可以不断添加删除元素
创建与添加
java
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
System.out.println("Names in the list:"+names);
}
}
拆解这一句ArrayList<String> names=new ArrayList<>();

问:ArrayList<String> names = new ArrayList<>(),这个创建一个空列表,右边的元素类型由左边推断是什么意思,括号里面<>()能不能自己写类型???
答:可以,这样写new ArrayList<String>(),<>是展示元素类型,()是调用构造方法。
读取、修改、删除
ArrayList也不能用类似的names0来访问元素,需要调用方法。
java
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
System.out.println("Names in the list:"+names);
System.out.println(names.get(0));
names.set(0,"David");
names.remove(1);
System.out.println("Names in the list after modifications:"+names);
}
}

包装类
ArrayList<int> nums = new ArrayList<>(); // 错误
ArrayList<Integer> nums = new ArrayList<>(); // 正确
因为Java的泛型类型参数不能直接使用基本类型,Integer是与int对应的包装类。

遍历方式
java
for(int i=0;i<nums.size();i++){
System.out.println(nums.get(i));
}
for(int num: nums){
System.out.println(num);
}
普通for、增强for。增强for的意思是依次取出nums中的每个整数,放入本轮的局部变量num。
练习,答案是变成了99,30,40。
java
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers=new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.set(1,99);
numbers.remove(0);
numbers.add(40);
System.out.println(numbers);
System.out.println("Size of the ArrayList: " + numbers.size());
}
}
学习进度

