1. API
API:(Application Programming Interface)应用程序编程接口
Java API:指的就是JDK中提供的各种功能的Java类
2. 解析Scanner类
Scanner:用于获取键盘录入数据。(基本数据类型,字符串数据)
//nextLine()方法的部分源代码,发现其返回值为String类型,故需要用String类型的变量接收其返回值
public String nextLine();
//获取键盘录入字符串数据
public class ScannerDemo {
public static void main(String[] args) {
//创建一个Scanner类的实例对象
Scanner sc = new Scanner(System.in);//new之后的Scanner(System.in)是一个有参构造方法
//接收数据
System.out.println("请输入一个字符串数据:");
String line = sc.nextLine();//用String类型的变量line接收对象sc调用的nextLine方法的返回值
/*String line = sc.nextLine();
可以只写等号右边的代码再按下 Ctrl+alt+v快速生成左边代码*/
//输出结果
System.out.println("你输入的数据时:" + line);
}
}
注意:调用方法时,如果方法有返回值,我们用变量接收时可以使用快捷键(Ctrl+alt+V)或者(alt+enter+enter)
3. String类介绍
String类代表字符串。Java程序中所有的字符串文字都被该类实现为实例。
Java程序中的所有双引号字符串,都是String类的对象
字符串的特点:
- 字符串不可变,它们的值在创建后不能被更改
- 虽然String的值不可变,但可以被共享
- 字符串效果上相当于字符数组(char[]),但是底层原理是字节数组(byte[])。(JDK8及以前是字符数组,JDK9及以后是字节数组)
4. String类的构造方法
方法名 | 说明 |
---|---|
public String() | 创建一个空白字符串对象,不含任何内容 |
public String(char[] chs) | 根据字符数组的内容,来创建字符串对象 |
public String(byte[] bys) | 根据字节数组的内容,来创建字符串对象 |
String s = “abc”; | 直接赋值的方式创建字符串对象,内容就是abc |
public class ScannerDemo {
public static void main(String[] args) {
//用String的无参构造方法创建一个对象
String s1 = new String();
System.out.println(s1);//没有输出其在内存中的地址,而是输出了空白
//有参构造创建对象,该方法需要一个字符数组参数
char[] chs = {'a','b','c'};
String s2 = new String(chs);
System.out.println(s2);//abc
//有参构造创建对象,该方法需要一个字节数组参数
byte[] bys = {97,98,99};
String s3 = new String(bys);
System.out.println(s3);//abc 内容被转换成底层ascII码对应的字符型参数返回了(97在ASCII码中代表字符a)
//不使用构造方法,直接赋值创建字符串对象s4
String s4 = "abc";
System.out.println(s4);//abc
}
}
5. String对象的特点
- 通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内容相同,但是地址值不同
char[] chs = {'a','b','c'};
String s1 = new String(chs);
String s2 = new String(chs);
在上面的代码中,JVM会首先创建一个字符数组,每一次new的时候都会有一个新的地址,对象s1和s2只是内容相同但在堆内存中的地址不同。
- 以""方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护
String s3 = "abc";
String s4 = "abc";
在第一行代码执行时,JVM会建立一个String对象放在字符串池中,并给s3参考,第二行代码则让s4直接参考字符串池中的String对象,也就是说它们本质上是同一个对象。
6. String内存分析
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 == s2);//false
//直接赋值方式创建对象
String s3 = "abc";
String s4 = "abc";
System.out.println(s3 == s4);//true
//比较字符串对象地址是否相同
System.out.println(s1 == s3);//false
}
-
创建的数组通过指针001指向堆中存储位置001。
-
使用构造方法创建的对象由指针指向堆内存中的存储位置002,003,再通过其找到数组的存储位置001。
-
使用直接赋值方式创建的对象s3内容存储在常量池中,通过栈内存中的指针指向常量池中的位置004;当创建对象s4时,因为s4的内容与s3一样,所以系统直接让对象s4的指针域s3一样指向004。
7. String中字符串的比较
使用 == 作比较
- 基本类型:比较的是数据值是否相同(包含整数型,浮点型,字符型,布尔值)
- 引用类型:比较的是其在内存中的地址值是否相同(包含类,接口,数组)
字符串是对象,比较内容时需要通过**equals()**方法
- 该方法部分源码:
public boolean equals(Object anObject)
- 方法表示将此字符串与指定对象进行比较。由于我们比较的是字符串对象,所以参数直接传递一个字符串
public static void main (String[] args) {
//使用构造方法创建对象
char[] chs = {'a','b','c'};
String s1 = new String(chs);//s1,s2地址存储在堆中,但是位置不相同
String s2 = new String(chs);
//直接赋值方式创建对象
String s3 = "abc";//s3,s4的地址存储在常量池中,当字符串内容相同时在常量池中的地址也相同
String s4 = "abc";
//比较字符串对象地址是否相同
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//false
System.out.println(s3 == s4);//true
//比较字符串内容是否相同
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
System.out.println(s3.equals(s4));//true
}
8. String中的常用方法
方法名 | 说明 |
---|---|
public boolean equals(Object anObject) | 比较字符串里的内容,严格区分大小写(用户名和密码) |
public char charAt(int index) | 返回指定索引处的char(字符)值 |
public int length() | 返回此字符串的长度 |
9. String Builder概述
有以下代码进行了字符串拼接操作
public static void main(String[] args){
String s = "hello";//创建时在常量池中开辟新空间存放
s += "world";//执行语句同时创建了"world"和"helloworld"两个字符串在常量池中
System.out.println(s);
}
其在内存中的情况如下图:
在这里插入图片描述
可以发现:对字符串进行拼接操作时,每次都会创建一个新的字符串,这种方式费时,费空间。
通过Java提供的String Builder类就可以解决这个问题。
-
String Builder是一个可变的字符串类,我们可以把它看成一个容器,可变指的是该对象的内容是可变的。
-
String和String Builder的区别:
- String:内容是不可变的
- String Builder:内容是可变的
10. String Builder的方法
10.1 构造方法
方法名 | 说明 |
---|---|
public StringBuilder() | 创建一个空白可变字符串对象,不含有任何内容 |
public StringBuilder(String str) | 根据字符串的内容来创建可变字符串对象 |
10.2 反转方法
方法名 | 说明 |
---|---|
public StringBuilder append(任意类型) | 添加数据,并返回对象本身 |
public StringBuilder reverse() | 返回相反的字符序列 |
//关于append()方法
public static void main(String[] args){
//创建对象
StringBuilder sb = new StringBuilder();
StringBuilder sb2 = sb.append("hello");
System.out.println(sb); //hello
System.out.println(sb2);//hello
System.out.println(sb == sb2);//true,结果为true说明两个对象在内存上的地址相同,本质上是同一个对象。也就是说对象sb在调用了append()方法后自身变成了调用它的对象sb,使该语句等价于StringBuilder sb2 = sb;
}
public static void main(String[] args){
//创建对象
StringBuilder sb = new StringBuilder();
//链式编程,该方法在执行结束后把sb.append()这句代码变成了对象sb,就导致其可以无线调用自己
sb.append("hello").append("world").append("java").append(100);
System.out.println(sb);//helloworldjava100
sb.reverse();
System.out.println(sb);//001avajdlrowolleh
}
11. String Builder和String相互转换
- String Builder转换为String
public String toString()
通过toString()就可以实现把String Builder转换为String
代码示例:
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("hello");
String s = sb.toString();//不能用String s = sb;进行转换
System.out.println(s);//hello
}
- String转换为String Builder
public StringBuilder(String s)
通过构造方法就可以实现把String转换为String转换为StringBuilder
代码示例:
public static void main(String[] args) {
String s = "hello";
StringBuilder sb = new StringBuilder(s);//使用构造方法来转换;不能用StringBuilder sb = s;进行转换
System.out.println(sb);//hello
}