一、常用类回顾
1.1. String类
-
String的声明:final修饰、实现了 Comparable接口
-
String的不可变性
-
String的两种定义方式
①字面量的定义方式:String s = “hello”; ②new的方式:String s = new String(“hello”);- Stirng的内存解析:字符串常量池、堆内存的使用使用
- String s = new String(“hello”); 在内存中创建了几个对象(2两个)
-
String的连接操作:+
- 常量+常量;变量+常量、变量+变量 、concat(String otherStirng);
- String intern();
-
熟悉String的构造器、与其他结构之间的转换、常用方法。
- 编码:字符、字符串—> 字节、字节数组。对应着编码集;
- 解码:字节、字节数组—> 字符、字符串对应着解码集
- 规则:解码集必须使用编码时使用的编码集
-
String相关的算法问题
1.2.StringBuffer、StringBuilder类
- [面试题]String、StringBuffer、StringBuilder的区别
- 知道什么场景下使用StringBuffer、StringBuilder
(一般涉及多线程的时候使用StringBuffer、StringBuilder)
1.3.jdk8之前的日期、时间API
- System的currentTimeMillis()
- 两个Date类的使用:
- SimpleDateFormate类:用于格式化、解析
- Calendar日历类的使用:抽象类
1.4.jdk8中的日期
- LocalDate、LocalTime、LocalDateTime —> 类似于Calendar;
- Instant —> 类似于Date
- DateTimeFormatter --> 类似于SimpleDateFormat
1.5. 比较器(重点)
- 自然排序涉及到 Comparable
- compareTo(Object obj)
- 定制排序涉及到 Comparator
- compare(Object obj1, Object obj2)
1.6.其他API
(了解)
二、企业面试题
2.1.String
1.以下两种方式创建 String对象的区别?
//先在堆空间创建一个对象,如果常量池中没有,也会创建一个
String str1 = new String("test");
//直接声明在字符串常量池中
String str2 = "test";
2.String s= new String(“xyz”);创建了几个String Object ?
两个,类似于上题的①
3.String a=“abc”;String b=“a”+“bc”,问a==b?
是!因为String b=“a”+“bc”; 中 “a” 和 “bc” 都是常量。
4.String中 “+” 怎么实现?
常量+常量:略
变量+常量、变量+变量:创建一个StringBuilder的实例,通过 append()添加字符串,最后调用 toString()方法返回一个字符串。(toString内部 new一个String的实例)
5.Java中 String是不是 final的?
类似问题:
- String被哪些类继承?
- 是否可以继承String类?
- String 是否可以继承?
因为String类是 final修饰的,所以它不能被继承。
6.String为啥不可变,在内存中的具体形态?
规定不可变。常量池中存放大家共有的字符串,节省内存空间;不用重新创建,提高效率。
String具体形态:提供常量池。jdk1.6(包括)之前,常量池在方法区;jdk1.7(包括)之后,常量池在堆区;
采用 new的方式创建对象,还是在堆空间创建对象
7.String可以在 switch中使用吗“?
可以,从jdk1.7开始可以使用
8.String中常用方法?
- 与其他结构转换
基本数据类型 --> String:
valueOf(num)
String --> 基本数据类型: 调用包装类的parseXxx(String s)
String —> char[],调用String.toCharArray()
String 转 byte[],调用 String.getBytes()方法
- 常用方法
- boolean isEmpty(); 判断字符串是否为空
- int length(); 返回字符串长度
- String concat(xx): 拼接字符 xx
- boolean equals(Object obj); 比较字符串是否相等
- boolean equalsIgnoreCase(Object obj); 比较字符串是否相等,不区分大小写
- int compareTo(String other): 比较字符串大小,区分大小写,按照
Unicode编码
比较大小- int compareToIgnoreCase(String other): 比较字符串大小,不区分大小写
- String toLowerCase(); 将字符串中大写字母转为小写字母
- String toUpperCase(); 将字符串中小写字母转为大写字母
- Stirng trim(): 去掉字符串前后空白符
- public String intern(): 结果在常量池中共享。
查找:
- boolean contains(xx): 是否包含xx
- int indexOf(xx); // 从前往后查找字符串中xx,如果有返回第一次出现的下标,没有找到返回 -1;
- int indexOf(String str, int fromIndex); // 返回子字符串在此字符串中 第一次出现的下标,从指定下标处开始搜索;
- int lastIndexOf(xx);//从后往前查找当前字符串中xx,如果有返回最后一次出现的下标,没有找到返回 -1;
- int lastIndexOf(String str, int fromIndex); 返回子字符串在此字符串中 最后一次出现的下标,从指定下标处开始反向搜索。
截取字符串
,返回截取后的字符串(截取内容,前包后不包):- String substring(int beginIndex);
String substring(int beginIndex, int endIndex); 注意取值范围是:[ beginIndex , endIndex )
String lastIndexOf(int ch);//从特定字符处截取字符串,返回后面的字符串
字符/字符数组相关:
- char charAt(index); 返回 [index]位置的字符
- char toCharArray(): 将此字符串转换为一个新的字符数组返回
- static String valueOf(char[] date): 返回指定数组中表示该字符序列的 String
- static String valueOf(char[] date, int offset, int count): 返回同上
- static String copyValueOf(char[] date): 返回同上
- static String copyValueOf(char[] date, int offset, int count): 返回同上
。。。。。。
9.subString() 到底做了什么?
String str = “hello”;
String subStr = str.subString(1, 3);//底层是 new的方式返回一个 subStr,实体内容是 “el”
也就是说,两次调用这个方法,创建的就是两个对象
2.2String、StringBuffer、StringBuilder
1. java中操作字符串有哪些类?有什么区别
类似问题
String、StringBuffer区别?
StringBuffer 和StringBuilder的区别?
StringBuffer 和StringBuilder的区别以及实现?
String:不可变的字符序列,底层使用 char[] (jdk8及之前);底层使用 byte[] (jdk8之后)
StringBuffer:可变的字符序列;jdk1.0声明,线程安全,效率较低;底层使用 char[] (jdk8及之前);底层使用 byte[] (jdk8之后)
StringBuffer:可变的字符序列;jdk5声明,线程不安全,效率较高;底层使用 char[] (jdk8及之前);底层使用 byte[] (jdk8之后)
扩容机制
StringBuffer和 StringBuilder都继承了 AbstractStringBuilder抽象类。
不断添加字符时,一旦超过 value.length时,就需要扩容。
默认扩容为原有容量的2倍+ 2
,并将原有 value数组中的元素复制到新的 char数组中。
特殊情况:原来容量的 2倍+ 2,还不满足时,需要多大容量就新建多大容量的数组
源码启示
- 开发中经常对字符进行字符串的增、删、改操作,建议使用StringBuffer 或StringBuilder替换String,因为String效率低,进行这些操作时 它的空间占用率较高;
- 开发中,不涉及线程安全问题时,建议使用 StringBuilder 替换StringBuffer。因为StringBuilder效率更高;
- 开发中若可以大体确定要操作的字符个数,建议使用带
int capacity
参数的 构造器。因为可以避免底层多次扩容操作,性能会更好。
2.String的线程安全问题
String是线程不安全的
3.StringBuffer、StringBuilder的线程安全问题
StringBuffer:可变的字符序列;jdk1.0声明,线程安全,效率较低;底层使用 char[] (jdk8及之前);底层使用 byte[] (jdk8之后)
StringBuffer:可变的字符序列;jdk5声明,线程不安全,效率较高;底层使用 char[] (jdk8及之前);底层使用 byte[] (jdk8之后)
2.3 Comparator和Comparable
1.Comparable和 Comparator的区别和场景?
- Comparable 自然排序
- Comparator 定制排序
1)角度一: - 自然排序:单一的、唯一的
- 定制排序:灵活的、多样的
2)角度二:
- 自然排序:一劳永逸
- 定制排序:临时的
3)角度三:细节
- 自然排序:对应的接口是Comparable,对应的抽象方法compareTo( Object obj);
- 定制排序:对应的接口是Comparator,对应的抽象方法compareTo( Object obj1, Object obj2);