- (重要)String类: String的修改非就地、String两种初始化:字面量(常量池)和new String(堆)。
- (重要)String初始化有区别:”abc”字面量 与 new String(“abc”)、字面量的拼接在常量池、变量与字面量的拼接在堆中(相当于new了)、拼接结果.intern()、理解不可变性。
- (重要)String常用方法: charAt(int)\compareTo(String,String)\substring(int,int)\startsWith(String,int)\contains(String)\indexOf(String,int)\lastIndexOf(String,int)\replace(char,char)\replace(String,String)\replaceAll(String regex,String)\matches(String regex)\split(String regex)\split(String,int)
- (重要)String与基本数据类型的转换。String.toCharArray(int) \ String.getChars(int srcBegin,int srcEnd, char[] dst) \ String(char[] ,int offset,int length) \ String.getBytes()
- (重要)StringBuilder类 和 StringBuffer类:String StringBuffer StringBuilder 区别 ? 、三者共同点:底层存储使用char[] (更新的jdk中是byte[])、 效率:String << StringBuffer < StringBuilder
- (老版,仅了解)日期时间类(JDK8之前): java.utils.System类时间戳、java.utils.Date类及其子类java.sql.Date类。
- (新版,重要)日期时间类(Jdk8): 建议:Date和Calendar类别用了,日期时间统一用下面的方法。
- (比较重要)比较器 : 重写Comparable接口的compareTo()方法(自然排序) 、 重写Comparator接口的compare()方法(定制排序)。
- System类
- Math类
- BigInteger类:任意整型
- BigDecimal类: 任意精度
(重要)String类: String的修改非就地、String两种初始化:字面量(常量池)和new String(堆)。
(重要)String初始化有区别:”abc”字面量 与 new String(“abc”)、字面量的拼接在常量池、变量与字面量的拼接在堆中(相当于new了)、拼接结果.intern()、理解不可变性。
注意: final String str = “123” 视为常量,因为它确实在常量池中, str + “123” 也在常量池中。
- 面试题: 答:ex.str依然为good。解释:进入函数时,str变量指向了this.str变量指向的实例, 但之后str被指向了”test ok”常量, 而这修改不是原地的,this.str变量依然指向原来的实例。结论:引用类型作为形式参数时,在函数内部并不一定能实现原地修改,上述String就是一个例外,它有不可变性。
- 个人总结来说:不可变性,即值是否可以被原地修改。目前来看,常量和String是不支持的。
class StringTest {
String str = new String("a");
public void change(String str) {
str = new String("b");
}
public static void main(String[] args) {
StringTest st = new StringTest();
st.change(st.str);
System.out.println(st.str); // a
}
}
(重要)String常用方法: charAt(int)\compareTo(String,String)\substring(int,int)\startsWith(String,int)\contains(String)\indexOf(String,int)\lastIndexOf(String,int)\replace(char,char)\replace(String,String)\replaceAll(String regex,String)\matches(String regex)\split(String regex)\split(String,int)
- 注意lastIndexOf即从指定位置从右到左的第一个
- 注:regex正则表达式:”\d+”: 一个或多个数字 “^,|,$”: 开头有逗号或结尾有逗号 “\d{7,8}”:有7到8位数字
- “hello|world”.split(“\|”) —>> {“hello” “world”}
(重要)String与基本数据类型的转换。String.toCharArray(int) \ String.getChars(int srcBegin,int srcEnd, char[] dst) \ String(char[] ,int offset,int length) \ String.getBytes()
- 编码: —> 字节码
- 解码: 字节码 —>
- String.getBytes() 默认字符集进行编码, String.getBytes(“gbks”) 指定gbks字符集进行编码。
(重要)StringBuilder类 和 StringBuffer类:String StringBuffer StringBuilder 区别 ? 、三者共同点:底层存储使用char[] (更新的jdk中是byte[])、 效率:String << StringBuffer < StringBuilder
- StringBuffer线程安全: 使用了同步方法。
- StringBuffer和StringBulider的选择:优先后者,仅在多线程时才使用StringBuffer。
StringBuffer常用方法: 注意append返回类型依然为StringBuffer。
StringBuffer源码分析:jdk11
总的来说,byte[]进行存储,默认构造器为new byte[0],所以为避免扩容操作推荐使用带参构造方法。扩容时,一般扩容1倍。另外,注意容量大小和数据长度的区别。
// 存储
byte[] value;
// 默认构造方法
private static final byte[] EMPTYVALUE = new byte[0];
AbstractStringBuilder() {
value = EMPTYVALUE;
}
// 带参构造方法
AbstractStringBuilder(int capacity) {
if (COMPACT_STRINGS) {
value = new byte[capacity];
coder = LATIN1;
} else {
value = StringUTF16.newBytesFor(capacity);
coder = UTF16;
}
}
// 其他带参构造方法。。。还有更多未写出
AbstractStringBuilder(String str) {
int length = str.length();
int capacity = (length < Integer.MAX_VALUE - 16)
? length + 16 : Integer.MAX_VALUE;
final byte initCoder = str.coder();
coder = initCoder;
value = (initCoder == LATIN1)
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
append(str);
}
// length()
public synchronized int length() {
return count;
}
// append()
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
int len = str.length();
ensureCapacityInternal(count + len);
putStringAt(count, str);
count += len;
return this;
}
// charAt()
public char charAt(int index) {
checkIndex(index, count);
if (isLatin1()) {
return (char)(value[index] & 0xff);
}
return StringUTF16.charAt(value, index);
}
// 容量大小
public int capacity() {
return value.length >> coder;
}
// ensureCapacityInternal 容量检查与扩容
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
int oldCapacity = value.length >> coder;
if (minimumCapacity - oldCapacity > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity) << coder);
}
}
// 扩容
private int newCapacity(int minCapacity) {
int oldLength = value.length;
int newLength = minCapacity << coder;
int growth = newLength - oldLength;
int length = ArraysSupport.newLength(oldLength, growth, oldLength + (2 << coder));
if (length == Integer.MAX_VALUE) {
throw new OutOfMemoryError("Required length exceeds implementation limit");
}
return length >> coder;
}
(老版,仅了解)日期时间类(JDK8之前): java.utils.System类时间戳、java.utils.Date类及其子类java.sql.Date类。
java.utils.System类时间戳
long time = System.currentTimeMillis(); // 自1970年1月1日零点。
java.utils.Date类及其子类java.sql.Date类。
java.text.SimpleDateFormat类: format()和parse()方法
java.text.SimpleDateFormat类, 格式化与解析。
public static void main(String[] args) throws ParseException {
// long data = System.currentTimeMillis(); // 自1970年1月1日零点。
Date data = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// 格式化:
String now = simpleDateFormat.format(data);
System.out.println(now);
// 解析(格式化的逆过程 ): 字符串到日期。 被解析的字符串要符合SimpleDateFormat构造器的格式。
Date date2 = simpleDateFormat.parse("2021-11-09 05:47:04");
System.out.println(date2);
}
java.utli.Calendar:它是抽象类、静态方法getInstance()
(新版,重要)日期时间类(Jdk8): 建议:Date和Calendar类别用了,日期时间统一用下面的方法。
LocalDateTime类。
瞬时 Instant类
java.time.format.DateTimeFormatter类: 格式化或解析日期时间。
其他api
新旧api转化
(比较重要)比较器 : 重写Comparable接口的compareTo()方法(自然排序) 、 重写Comparator接口的compare()方法(定制排序)。
- Comparable和Comparator的使用区别: 通用与临时。
比如,按照商品价格排序。compareTo()规则: 返回1、 -1、 0。