常用API(String、ArrayList)
12131231
# 常用
# 1. API
# 1.1 API概述
什么是API
API (Application Programming Interface) :应用程序编程接口
java中的API
指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。
# 2. String类
# 2.1 String类概述
String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!
String 是字符串类型,可以定义字符串变量指向字符串对象。
# 2.2 String类的特点
- String 常被称为不可变字符串类型,它的对象在创建后不能被更改。
- 虽然 String 的值是不可变的,但是它们可以被共享
- 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
字符串对象存在哪里?
💡 以 “” 方式给出的字符串对象,在字符串常量池中存储。
上图中,首先由 ""
给出了“传智”字符串常量,存储于字符串常量池;执行到当前此行时,将”教育“也存入字符串常量池,二者拿来做运算,新运算得到的对象“传智教育”直接放在堆内存中,并将 name
(String 类变量)指向新的这个对象。因此 String 的对象创建出来之后的确未改变,只是每次都在指向新的对象,故说 String 的对象是不可变对象。
下图同理。
String 是不可变字符串的原因?
- String 变量每次的修改其实都是产生并指向了新的字符串对象。
- 原来的字符串对象都是没有改变的,所以称不可变字符串。
# 2.3 String类创建对象的2种方式
# 2.3.1 两种方式
方式一:直接使用“”定义。(推荐方式)
String name = "Nrich";
方式二:通过String类的构造器创建对象。
- 常用的构造方法:
构造器 说明 public String() 创建一个空白字符串对象,不含有任何内容(基本不用) public String(String original 根据传入的字符串内容,来创建字符串对象(基本不用) public String(char[] chs) 根据字符数组的内容,来创建字符串对象 public String(byte[] chs) 根据字节数组的内容,来创建字符串对象 示例代码
public class StringDemo01 { public static void main(String[] args) { //public String():创建一个空白字符串对象,不含有任何内容 [基本不用] String s1 = new String(); System.out.println("s1:" + s1); //public String(char[] chs):根据字符数组的内容,来创建字符串对象 char[] chs = {'a', 'b', 'c'}; String s2 = new String(chs); System.out.println("s2:" + s2); //public String(byte[] bys):根据字节数组的内容,来创建字符串对象 byte[] bys = {97, 98, 99}; String s3 = new String(bys); System.out.println("s3:" + s3); //String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc String s4 = "abc"; System.out.println("s4:" + s4); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.3.2 两种方式的区别?
以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份,以节省内存资源。
下图中比较结果为 true,因为比较的是变量中所存的地址,输出是地址中的内容是因为做了别的处理。
通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中。
代码示例:
String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); // true char[] chs = {'a', 'b', 'c'}; String s3 = new String(chs); String s4 = new String(chs); System.out.println(s3 == s4); // false
1
2
3
4
5
6
7
8
9
# 2.3.3 String 常见面试题
问题 1 :下列代码的运行结果是?
public class Test2 {
public static void main(String[] args) {
String s2 = new String("abc");
String s1 = "abc";
System.out.println(s1 == s2);
}
}
2
3
4
5
6
7
8
9
结果:false ⚠️
说明:
Line 4 实际上创建了两个对象,“abc” 在字符串常量池创建了一个,new 又在堆内存创建了一个。
Line 6 实际上没有创建对象,直接共用 Line 4 在字符串常量池中创建的对象。
堆内存图如下:
问题 2 :下列代码的运行结果分别是?
public class Test3 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c";
System.out.println(s1 == s3);
}
}
2
3
4
5
6
7
8
结果:false
public class Test4 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "a" + "b" + "c";
System.out.println(s1 == s2);
}
}
2
3
4
5
6
7
结果:true ⚠️
说明:Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 "abc"。因为在编译时已可以确定这个值是啥,故不等到运行时再浪费性能进行计算。但当存在变量时,无法在编译阶段确定值是啥。
# 2.4 字符串内容比较
# 2.4.1 == 号的作用
- 比较基本数据类型:比较的是具体的值
- 比较引用数据类型:比较的是对象地址值
# 2.4.2 equals 方法的作用
方法名 | 说明 |
---|---|
public boolean equals (Object anObject) | 将此字符串与指定对象进行比较。只关心字符内容是否一致! |
public boolean equalsIgnoreCase (String anotherString) | 将此字符串与指定对象进行比较,忽略大小写比较字符串。只关心字符内容是否一致! |
示例代码
public class StringDemo02 { public static void main(String[] args) { //构造方法的方式得到对象 char[] chs = {'a', 'b', 'c'}; String s1 = new String(chs); String s2 = new String(chs); //比较字符串内容是否相同 System.out.println(s1.equals(s2)); } }
1
2
3
4
5
6
7
8
9
10
11
# 2.5 String 其他常用API
提示
Ctrl + Alt + V
可以直接生成变量- 截取倒数第 7 位到倒数第 4 位的子串:
s.substring(s.length()-7, s.length()-4)
# 3. ArrayList
# 3.1 集合概述
集合是与数组类似,也是一种容器,用于装数据的。
数组的特点:
数组定义完成并启动后,类型确定、长度固定。
集合的特点
集合的大小不固定,启动后可以动态变化,类型也可以选择不固定。
集合非常适合做元素个数不确定,且要进行增删操作的业务场景。
集合还提供了许多丰富、好用的功能,而数组的功能很单一。
💡 注:集合中存储的元素并不是对象本身,而是对象的地址。
# 3.2 ArrayList 集合
ArrayList是集合中的一种,它支持索引。底层是数组实现的,长度可以变化。
# 3.2.1 ArrayList集合的对象获取
使用构造器 public ArrayList()
,创建一个空的集合对象。如:ArrayList list = new ArrayList();
# 3.2.2 ArrayList 对于泛型的支持
ArrayList<E>
:一个泛型类,可以在编译阶段约束集合对象只能操作某种 E 数据类型。
例如:
ArrayList<String> :此集合只能操作字符串类型的元素。
ArrayList<Integer>:此集合只能操作整数类型的元素。
⚠️ 注意:
集合中只能存储引用类型,不支持基本数据类型。
ArrayList 一般都会使用泛型,哪怕需要啥类型都支持,也会加 ArrayList<Object>。
# 3.3 ArrayList 集合常用方法
- ArrayList 集合添加元素的方法:
- ArrayList 集合其他常用方法:
# 3.4 ArrayList 集合易错点:遍历并删除元素
错误做法:
public class ArrayListTest {
public static void main(String[] args) {
//创建集合对象
ArrayList<Integer> scores = new ArrayList<>();
//添加成绩到集合中
scores.add(98);
scores.add(20);
scores.add(78);
//遍历集合,采用通用遍历格式实现
for (int i = 0; i < scores.size(); i++) {
int score = scores.get(i);
if (score < 80){
// 去掉成绩低于80分的
scores.remove(i);
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
出现的问题:
采用以上的常规 fori 形式边遍历边删除,会导致漏删部分元素。因为 ArrayList 的长度是动态变化的,删除之后会出现补位的情况。
解决:
① remove 之后, i-- 。即 Line 16 之后添加 i--;
② 从集合后面倒着遍历然后删除,代码如下:
for (int i = scores.size() - 1; i >= 0 ; i--) {
int score = scores.get(i);
if (score < 80){
scores.remove(i);
}
}
2
3
4
5
6