一、随堂复习
1. String类
-
String的声明:final修饰、实现了Comparable接口
-
String的不可变性
-
String的两种定义方式:① 字面量的定义方式 String s = "hello" ② new 的方式:String s = new String("hello");
-
String的内存解析:字符串常量池、堆内存的使用
-
String s = new String("hello");在内存中创建的对象的个数。
-
-
String的连接操作:+
-
常量 + 常量 、变量 + 常量 、变量+变量、concat(String otherString)
-
String intern()
-
-
熟悉String的构造器、与其他结构之间的转换、常用方法
-
编码和解码
-
编码:字符、字符串 --> 字节、字节数组。对应着编码集
-
解码:字节、字节数组 --> 字符、字符串。对应着解码集
-
规则:解码集必须使用当初编码时使用的编码集。只要不一致,就可能出现乱码!
-
-
-
String相关的算法问题。
2. StringBuffer、StringBuilder类
-
[面试题]String、StringBuffer、StringBuilder的区别
-
知道什么场景下使用StringBuffer、StringBuilder
3. jdk8之前的日期、时间API
-
System的currentTimeMillis()
-
两个Date的使用
-
SimpleDateFormat用于格式化、解析
-
Calendar日历类的使用
4. jdk8中新的日期、时间API
-
LocalDate、LocalTime、LocalDateTime -->类似于Calendar
-
Instant -->类似于Date
-
DateTimeFormatter --->类似于SimpleDateFormat
5. 比较器(重点)
-
自然排序涉及到Comparable
-
compareTo(Object obj)
-
-
定制排序涉及到Comparator
-
compare(Object obj1,Object obj2)
-
6. 其它API
了解
二、企业真题
2.1 String
1. 以下两种方式创建的String对象有什么不同?(*团)
String str = new String("test"); String str = "test";
前者:
一个是堆空间中new的对象。另一个是在字符串常量池中生成的字面量。
后者:
是在字符串常量池中生成的字面量。
2. String s = new String("xyz");创建了几个String Object? (新*陆)
两个
3. String a="abc" String b="a"+"bc" 问a==b?(网*邮箱)
是!
4. String 中 “+” 怎样实现?(阿*)
常量 + 常量 :
结果仍然存储在字符串常量池中,返回此字面量的地址。注:此时的常量可能是字面量,也可能是final修饰的常量
变量 + 常量 、变量+变量:
创建一个StringBuilder的实例,通过append()添加字符串,最后调用toString()返回一个字符串。(toString()内部new 一个String的实例)
5. Java中String是不是final的?(凡*科技)
类似问题: > String被哪些类继承?(网*邮箱) > 是否可以继承String类?(湖南*利软件) > String 是否可以继承?(阿*)
是
6. String为啥不可变,在内存中的具体形态?(阿*)
① 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改 ② 当对现有的字符串进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有的位置修改 ③ 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改
规定不可变。
String:提供字符串常量池。
7. String 可以在 switch中使用吗?(上海*睿)
可以。从jdk7开始可以使用
8. String中有哪些方法?列举几个(闪*购)
(1)boolean isEmpty():字符串是否为空 (2)int length():返回字符串的长度 (3)String concat(xx):拼接 (4)boolean equals(Object obj):比较字符串是否相等,区分大小写 (5)boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写 (6)int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小 (7)int compareToIgnoreCase(String other):比较字符串大小,不区分大小写 (8)String toLowerCase():将字符串中大写字母转为小写 (9)String toUpperCase():将字符串中小写字母转为大写 (10)String trim():去掉字符串前后空白符 (11)public String intern():结果在常量池中共享 (12)boolean contains(xx):是否包含xx (13)int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-1 (14)int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始 (15)int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-1 (16)int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 (17)String substring(int beginIndex) :返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。 (18)String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。 (19)char charAt(index):返回[index]位置的字符 (20)char[] toCharArray(): 将此字符串转换为一个新的字符数组返回 (21)static String valueOf(char[] data) :返回指定数组中表示该字符序列的 String (22)static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String (23)static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String (24)static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String (25)boolean startsWith(xx):测试此字符串是否以指定的前缀开始 (26)boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始 (27)boolean endsWith(xx):测试此字符串是否以指定的后缀结束
9. subString()到底做了什么?(银*数据)
String str = "hello";
String subStr = str.subString(1,3); //底层是new的方式返回一个subStr,实体内容是"el"
2.2 String、StringBuffer、StringBuilder
1. Java中操作字符串有哪些类?他们之间有什么区别。(南*电网)
类似问题: > String 和 StringBuffer区别?(亿*国际、天*隆、*团) > StringBuilder和StrignBuffer的区别?(平*金服) > StringBuilder和StringBuffer的区别以及实现?(*为)
> String:不可变的字符序列;底层使用char[] (jdk8及之前),底层使用byte[] (jdk9及之后) > StringBuffer:可变的字符序列;JDK1.0声明,线程安全的,效率低;底层使用char[] (jdk8及之前),底层使用byte[] (jdk9及之后) > StringBuilder:可变的字符序列;JDK5.0声明,线程不安全的,效率高;底层使用char[] (jdk8及之前),底层使用byte[] (jdk9及之后)
2. String的线程安全问题(闪*购)
线程不安全的
3. StringBuilder和StringBuffer的线程安全问题(润*软件)
> StringBuffer:可变的字符序列;JDK1.0声明,线程安全的,效率低;底层使用char[] (jdk8及之前),底层使用byte[] (jdk9及之后) > StringBuilder:可变的字符序列;JDK5.0声明,线程不安全的,效率高;底层使用char[] (jdk8及之前),底层使用byte[] (jdk9及之后)
2.3 Comparator与Comparable
1. 简单说说 Comparable 和 Comparator 的区别和场景?(软**力)
1.实现对象的排序,可以考虑两种方法:自然排序 、 定制排序 2. 方式一: 实现步骤: ① 具体的类A实现Comparable接口 ② 重写Comparable接口中的compareTo(Object obj)方法,在此方法中指明比较类A的对象的大小的标准 ③ 创建类A的多个实例,进行大小的比较或排序。 3. 方式二: 实现步骤: ① 创建一个实现了Comparator接口的实现类A ② 实现类A要求重写Comparator接口中的抽象方法compare(Object o1,Object o2),在此方法中指明要 比较大小的对象的大小关系。(比如,String类、Product类) ③ 创建此实现类A的对象,并将此对象传入到相关方法的参数位置即可。(比如:Arrays.sort(..,类A的实例)) 4. 对比两种方式: 角度一: 自然排序:单一的,唯一的 定制排序:灵活的,多样的 角度二: 自然排序:一劳永逸的 定制排序:临时的 角度三:细节 自然排序:对应的接口是Comparable,对应的抽象方法compareTo(Object obj) 定制排序:对应的接口是Comparator,对应的抽象方法compare(Object obj1,Object obj2)
2. Comparable 接口和 Comparator 接口实现比较(阿*)
Comparable
package com.atguigu04.compare.comparable;
import com.atguigu04.compare.Product;
import org.junit.Test;
import java.util.Arrays;
/**
* ClassName: ComparableTest
* Package: com.atguigu04.compare.comparable
* Description:
*
* @Author 随心油条
* @Create 2024/4/12 19:22
* @Version 1.0
*/
public class ComparableTest {
@Test
public void test1(){
String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};
Arrays.sort(arr);
//排序后遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
@Test
public void test2(){
Product[] processes = new Product[5];
processes[0] = new Product("HuaweiMate50pro",6299);
processes[1] = new Product("Xiaomi13pro",4999);
processes[2] = new Product("VivoX90pro",5999);
processes[3] = new Product("Iphone14ProMax",9999);
processes[4] = new Product("HonorMagic4",6299);
Arrays.sort(processes);
for (int i = 0; i < processes.length; i++) {
System.out.println(processes[i]);
}
}
@Test
public void test3(){
Product p1 = new Product("HuaweiMate50pro",6299);
Product p2 = new Product("VivoX90pro",5999);
int compare = p1.compareTo(p2);
if (compare != 0) {
if (compare > 0){
System.out.println("p1大");//p1大
}else if (compare < 0){
System.out.println("p2大");
}else {
System.out.println("一样大");
}
}
}
}
comparator:
package com.atguigu04.compare.comparator;
import com.atguigu04.compare.Product;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
/**
* ClassName: ComparatorTest
* Package: com.atguigu04.compare.comparator
* Description:
*
* @Author 随心油条
* @Create 2024/4/12 20:17
* @Version 1.0
*/
public class ComparatorTest {
@Test
public void test1(){
Product[] processes = new Product[5];
processes[0] = new Product("HuaweiMate50pro",6299);
processes[1] = new Product("Xiaomi13pro",4999);
processes[2] = new Product("VivoX90pro",5999);
processes[3] = new Product("Iphone14ProMax",9999);
processes[4] = new Product("HonorMagic4",6299);
//创建一个实现了Comparator接口的实现类的对象
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Product && o2 instanceof Product){
Product product1 = (Product) o1;
Product product2 = (Product) o2;
int compare = Double.compare(product1.getPrice(),product2.getPrice());
return compare;
}
//手动抛出一个异常类的对象
throw new RuntimeException("输入类型不匹配");
}
};
//如果判断两个对象o1,o2的大小,其标准就是此方法的方法体要编写的逻辑。
//比如:按照name从低到高排序
//创建一个实现了Comparator接口的实现类的对象
Comparator comparator1 = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Product && o2 instanceof Product){
Product product1 = (Product) o1;
Product product2 = (Product) o2;
int compare = product1.getName().compareTo(product2.getName());
return compare;
}
//手动抛出一个异常类的对象
throw new RuntimeException("输入类型不匹配");
}
};
// Arrays.sort(processes,comparator);
Arrays.sort(processes,comparator1);
for (int i = 0; i < processes.length; i++) {
System.out.println(processes[i]);
}
}
@Test
public void test2(){
String[] arr = new String[]{"Tom","Jerry","Tony","Rose","Jack","Lucy"};
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof String && o2 instanceof String){
String s1 = (String) o1;
String s2 = (String) o2;
int compare = -s1.compareTo(s2);
return compare;
}
throw new RuntimeException("输入类型有误");
}
};
Arrays.sort(arr,comparator);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}