目录
3.3 SimpleDateFormat类(java8之前)
3.6 DateTimeFormatter类( Java8)
1. String类
1.1 java.lang.String类
- 用于描述字符串,Java程序中所有的字符串字面值都可以使用该类的对象加以描述;
- 该类由
final
关键字修饰,表示该类不能被继承;- 从
jdk1.9
开始该类的底层不使用char[](2字节)
来存储数据,而是改成byte[](1字节)
加上编 码标记,从而节约了一 些空间;- 该类描述的字符串内容是个常量不可更改,因此可以被共享使用。
1.2 什么是常量池?
-- 由于String类型描述的字符串内容是常量不可改变,因此Java虚拟机将首次出现的字符串放入常量池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能。
案例:
public class StringTest {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
System.out.println(str3 == str4);
System.out.println(str3.equals(str4));
}
}
运行结果:
true、true、false、true
分析:
-- 双引号引起的字符串存放在常量池,对于重复出现的字符串来说直接使用池中已有的对象,因此地址相同。
使用 new 关键字创建字符串的方式会在堆区重新申请内存空间,因此对象不一样,地址不同,但是 String 类中重写了 equals 方法,因此比较字符串内容是否相同。
1.3 String类常用构造方法
方法声明 | 功能介绍 |
---|---|
String() | 使用无参方式构造对象得到空字符串对象 |
String(byte[] bytes(字节数组名), int offset, int length) | 使用bytes(字节)数组中下标从offset位置开始的length个字节来构造字符串对象; |
String(byte[] bytes) | 使用整个bytes数组构造字符串对象 |
String(char[] value(字符数组名), int offset, int count) | 使用字符数组中下标从offset位置开始的count个字符来构造对象 |
String(char[] value) | 使用整个字符数组来构造对象 |
代码示例:
public class StringConstructorTest {
public static void main(String[] args) {
// 1.使用无参方式构造对象并打印
String str1 = new String();
// "" 表示空字符串对象,有对象只是里面没有内容
// null 表示空,连对象都没有
System.out.println("str1 = " + str1); // "" 自动调用toString方法
System.out.println("----------------------------------------------------");
// 2.使用参数指定的byte数组来构造对象并打印
// 'a' - 97
byte[] bArr = {97, 98, 99, 100, 101};
// 使用字节数组中的一部分内容来构造对象,表示使用数组bArr中下标从1开始的3个字节构造字符串对象
// 构造字符串的思路:就是先将每个整数翻译成对应的字符,再将所有的字符串起来。
// 98 - 'b' 99 - 'c' 100 - 'd' => bcd
String str2 = new String(bArr, 1, 3);
System.out.println("str2 = " + str2); // bcd
// 使用整个字节数组来构造字符串对象
String str3 = new String(bArr);
System.out.println("str3 = " + str3); // abcde
System.out.println("----------------------------------------------------");
// 3.使用字符数组来构造字符串对象
char[] cArr = {'h', 'e', 'l', 'l', 'o'};
// 使用字符数组中的一部分内容来构造对象
// 思路:直接将字符串起来
String str4 = new String(cArr, 2, 2);
System.out.println("str4 = " + str4); // ll
// 使用整个字符数组来构造对象
String str5 = new String(cArr);
System.out.println("str5 = " + str5); // hello
System.out.println("----------------------------------------------------");
// 4.使用字符串来构造字符串对象
String str6 = new String("world");
System.out.println("str6 = " + str6); // world
}
}
1.4 String类常用成员方法
1.4.1 String类型和数组之间的转换的方法
方法声明 | 功能介绍 |
---|---|
String toString() | 返回字符串本身 |
byte[] getBytes() | 将当前字符串内容转换为byte数组并返回(其中的原理就是:先将字符串拆分成字符,再将每个字符转换成byte类型,也就是获取所有字符的ASCII值); |
char[] toCharArray() | 用于将当前字符串内容转换为char数组并返回; |
代码示例:
public class StringByteCharTest {
public static void main(String[] args) {
// 1.创建String类型的对象并打印
String str1 = new String("world");
System.out.println("str1 = " + str1); // world
System.out.println("-----------------------------------------------");
// 2.实现将String类型转换为byte数组类型并打印
// 思路:先将字符串拆分为字符,将再每个字符转换为byte类型,也就是获取所有字符的ASCII
byte[] bArr = str1.getBytes();
for (int i = 0; i < bArr.length; i++) {
System.out.println("下标为i的元素是:" + bArr[i]);
}
// 将byte数组转回String类型并打印
String str2 = new String(bArr);
System.out.println("转回字符串为:" + str2); // world
System.out.println("-----------------------------------------------");
// 3.实现将String类型转换为char数组类型并打印
// 思路:将字符串拆分为字符并保存到数组中
char[] cArr = str1.toCharArray();
for (int i = 0; i < cArr.length; i++) {
System.out.println("下标为" + i + "的字符是:" + cArr[i]);
}
// 将char数组转回String类型并打印
String str3 = new String(cArr);
System.out.println("转回字符串为:" + str3); // world
}
}
1.4.2 String类中字符的获取与使用的方法
方法声明 | 功能介绍 |
---|---|
char charAt(int index) | 方法charAt() 用于返回字符串指定位置的字符; |
int length() | 返回字符串字符序列的长度; |
boolean isEmpty() | 判断字符串是否为空; |
代码示例:
public class StringCharTest {
public static void main(String[] args) {
// 1.构造String类型的对象并打印
String str1 = new String("hello");
System.out.println("str1 = " + str1); // hello
// 2.获取字符串的长度和每个字符并打印
System.out.println("字符串的长度是:" + str1.length()); // 5
System.out.println("下标为0的字符是:" + str1.charAt(0)); // h
System.out.println("下标为1的字符是:" + str1.charAt(1)); // e
System.out.println("下标为2的字符是:" + str1.charAt(2)); // l
System.out.println("下标为3的字符是:" + str1.charAt(3)); // l
System.out.println("下标为4的字符是:" + str1.charAt(4)); // o
//System.out.println("下标为5的字符是:" + str1.charAt(5)); // StringIndexOutOfBoundsException 字符串下标越界异常
System.out.println("----------------------------------------------");
// 3.使用for循环获取所有字符
for (int i = 0; i < str1.length(); i++) {
System.out.println("下标为" + i + "的字符是:" + str1.charAt(i)); // h e l l o
}
System.out.println("----------------------------------------------");
// 4.判断字符串是否为空
System.out.println(0 == str1.length()? "字符串为空": "字符串不为空"); // 不为空
System.out.println(str1.isEmpty()? "字符串为空": "字符串不为空"); // 不为空
System.out.println("----------------------------------------------");
// 5. 使用两种方式实现字符串"12345"转换为整数12345并打印
String str2 = new String("12345");
// 方式一:调用Integer类中的parseInt()方法即可
int ia = Integer.parseInt(str2);
System.out.println("转换出来的整数是:" + ia); // 12345
// 方式二:利用ASCII来实现类型转换并打印
// '1' - '0' => 1 '2' - '0' => 2 ...
int ib = 0;
for (int i = 0; i < str2.length(); i++) {
ib = ib*10 + (str2.charAt(i) - '0'); // 1 12 ...
}
System.out.println("转换出来的结果是:" + ib); // 12345
System.out.println("----------------------------------------------");
// 6. 如何实现整数到字符串的转换
//String str3 = String.valueOf(ib);
String str3 = "" + ib; // 推荐使用
System.out.println("str3 = " + str3); // 12345
}
}
1.4.3 String类中字符的比较的方法
方法声明 | 功能介绍 |
---|---|
int compareTo(String anotherString) | 用于比较调用对象和参数对象的大小关系; |
int compareToIgnoreCase(String str) | 不考虑大小写,也就是'a'和'A'是相等的关系; |
String concat(String str) | 用于实现字符串的拼接; |
boolean contains(CharSequence s) | 用于判断当前字符串是否包含参数指定的内容; |
boolean equals(Object anObject) | 用于比较字符串内容是否相等并返回 ; |
int hashCode() | 获取调用对象的哈希码值; |
boolean equalsIgnoreCase(String anotherString) | 用于比较字符串内容是否相等并返回,不考虑大小写,如:'A'和'a'是相等; |
1.4.4 String类中字符的查找的方法
方法声明 | 功能介绍 |
---|---|
int indexOf(int ch) | 用于返回当前字符串中参数ch指定的字符第一次出现的下标; |
int indexOf(int ch, int fromIndex) | 用于从fromIndex位置开始查找ch指定的字符; |
int indexOf(String str) | 在字符串中检索str返回其第一次出现的位置,若找不到返回-1; |
int indexOf(String str, int fromIndex) | 表示从字符串的fromIndex位置开始检索str第一次出现的位置; |
int lastIndexOf(int ch) | 用于返回参数ch指定的字符最后一次出现的下标; |
int lastIndexOf(int ch, int fromIndex) | 用于从fromIndex位置开始查找ch指定字符出现的下标 ; |
int lastIndexOf(String str) | 返回str指定字符串最后一次出现的下标; |
int lastIndexOf(String str, int fromIndex) | 用于从fromIndex位置开始反向搜索的第一次出现的下标。 |
1.4.5 String类中子字符串的获取的方法
方法声明 | 功能介绍 |
---|---|
String substring(int beginIndex, int endIndex) | 返回字符串中从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串; |
String substring(int beginIndex) | 返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串; |
2. StringBuilder类
2.1 可变字符串类
-- java.lang.StringBuilder 和 java.lang.StringBuffer
概念:
- 由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串时,只能单独申请和存储,此时会造成内存空间的浪费。
- 为了解决上述问题,可以使用
java.lang.StringBuilder
类 和java.lang.StringBuffer
类来描述字符序列可以改变的字符串,如:"ab"。- StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。
- StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。
2.2 StringBuilder类中常用构造方法
方法声明 | 功能介绍 |
---|---|
StringBuilder() | 使用无参方式构造对象,容量为16(即:初始容量为16); |
StringBuilder(int capacity) | 根据参数指定的容量来构造对象,容量为参数指定大小; |
StringBuilder(String str) | 根据参数指定的字符串来构造对象,容量为:16+字符串长度; |
2.3 StringBuilder类常用的成员方法
方法声明 | 功能介绍 |
---|---|
int capacity() | 用于返回调用对象的容量; |
int length() | 用于返回字符串的长度,也就是字符的个数; |
StringBuilder insert(int offset, String str) | 插入字符串并返回调用对象的引用,就是自己; |
StringBuilder append(String str) | 追加字符串 |
StringBuilder deleteCharAt(int index) | 将当前字符串中下标为index位置的单个字符删除 ; |
StringBuilder delete(int start,int end) | 删除字符串,从下标为start开始到下标为end结束(包含start,不包含end); |
StringBuilder replace(int start,int end,String str) | 替换字符串 (改); |
StringBuilder setCharAt(int index,String ch) | 将下标为:index的位置的字符修改为:ch; |
int indexOf(int ch) | 用于返回当前字符串中参数ch指定的字符第一次出现的下标(查); |
StringBuilder reverse() | 字符串反转; |
代码示例:
public class StringBuilderTest {
public static void main(String[] args) {
// 1.使用无参方式构造StringBuilder类型的对象并打印容量和长度
StringBuilder sb1 = new StringBuilder();
System.out.println("sb1 = " + sb1); // 自动调用toString方法 啥也没有
System.out.println("容量是:" + sb1.capacity()); // 16
System.out.println("长度是:" + sb1.length()); // 0
System.out.println("-----------------------------------------------------------");
// 2.使用参数指定的容量来构造对象并打印容量和长度
StringBuilder sb2 = new StringBuilder(20);
System.out.println("sb2 = " + sb2); // 自动调用toString方法 啥也没有
System.out.println("容量是:" + sb2.capacity()); // 20
System.out.println("长度是:" + sb2.length()); // 0
System.out.println("-----------------------------------------------------------");
// 3.根据参数指定的字符串内容来构造对象并打印容量和长度
StringBuilder sb3 = new StringBuilder("hello");
System.out.println("sb3 = " + sb3); // 自动调用toString方法 hello
System.out.println("容量是:" + sb3.capacity()); // 16 + 5 = 21
System.out.println("长度是:" + sb3.length()); // 5
System.out.println("-----------------------------------------------------------");
String str1 = new String("hello");
String str2 = str1.toUpperCase();
System.out.println("str2 = " + str2); // HELLO
System.out.println("str1 = " + str1); // hello 字符串本身是个常量不会改变
// 4.实现向字符串中插入和追加字符串内容
// 向下标为0的位置插入字符串内容"abcd",也就是向开头位置插入字符串内容
StringBuilder sb4 = sb3.insert(0, "abcd");
System.out.println("sb4 = " + sb4); // abcdhello 返回调用对象自己的引用,也就是返回值和调用对象是同一个字符串
System.out.println("sb3 = " + sb3); // abcdhello
// 向中间位置插入字符串"1234"
sb3.insert(4, "1234");
System.out.println("sb3 = " + sb3); // abcd1234hello
// 向末尾位置插入字符串"ABCD"
sb3.insert(sb3.length(), "ABCD");
System.out.println("sb3 = " + sb3); // abcd1234helloABCD
System.out.println("-----------------------------------------------------------");
// 向末尾位置追加字符串内容
sb3.append("world");
System.out.println("sb3 = " + sb3); // abcd1234helloABCDworld
// 当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量*2 + 2 => 21*2 + 2 => 44
// 底层采用byte数组来存放所有的字符内容。
System.out.println("容量是:" + sb3.capacity()); // 44
System.out.println("长度是:" + sb3.length()); // 22
System.out.println("-----------------------------------------------------------");
// 5.实现字符串中字符和字符串的删除
// 表示删除下标为8的单个字符
sb3.deleteCharAt(8);
System.out.println("sb3 = " + sb3); // abcd1234elloABCDworld
// 使用for循环删除多个字符
for (int i = 8; i < 12; i++) {
// 由结果可知:删除一个字符后就跳过一个字符继续删除,因为每当删除一个字符后后面的字符会向前补位,因为下标会发生变化
//sb3.deleteCharAt(i);
// 始终删除下标为8的字符
sb3.deleteCharAt(8);
}
System.out.println("删除后的字符串是:" + sb3); // abcd1234ABCDworld
System.out.println("-----------------------------------------------------------");
// 删除起始字符串abcd,包含0但不包含4
sb3.delete(0, 4);
System.out.println("sb3 = " + sb3); // 1234ABCDworld
// 删除中间字符串
sb3.delete(4, 8);
System.out.println("sb3 = " + sb3); // 1234world
// 删除末尾字符串
sb3.delete(4, sb3.length());
System.out.println("sb3 = " + sb3); // 1234
System.out.println("-----------------------------------------------------------");
// 6.实现字符串内容的修改、查找以及反转操作
// 表示将下标为0这个位置的字符修改为'a'
sb3.setCharAt(0, 'a');
System.out.println("修改单个字符后的内容是:" + sb3); // a234
// 修改"234"为"bcd"
sb3.replace(1, 4, "bcd");
System.out.println("修改字符串后的结果是:" + sb3); // abcd
// 实现查找的功能
int pos = sb3.indexOf("b");
System.out.println("从前向后查找的结果是:" + pos); // 1
pos = sb3.lastIndexOf("b");
System.out.println("从后向前查找的结果是:" + pos); // 1
// 实现字符串的反转功能
sb3.reverse();
System.out.println("反转后的结果是:" + sb3); // dcba
}
}
注意事项:
- 当字符串的长度超过字符串对象的初始容量时,该字符串对象会自动扩容,扩容算法是:原始容量*2+2。底层采用byte数组存放所有的字符内容;
- StringBuilder的很多方法的返回值均为StringBuilder类型。这些方法的返回语句均为:return this。由此可见,这些方法在对StringBuilder所 封装的字符序列进行改变后又返回了该对象的引用。基于这样设计的目的在于可以连续调用。
思考:
1. 既然StringBuilder类的对象本身就可以改变,那为什么成员方法还有返回值呢?
答:这其实就是为了可以连续调用。如:
sb.reverse().append("1").insert(0,"2");
2. 如何实现String类型和StringBuilder类型转换?
StringBuilder sb = new StringBuilder();
String str = sb.toString(); // StringBuilder类型转成 String类型
StringBuilder sb2 = new StringBuilder(str); // String类型转成 StringBuilder类型
3. 三个类的效率排序:String<StringBuffer<StringBuilder.
3. 日期类
3.1 System类(java8之前)
-- Java.lang.System
类
常用的方法:
方法声明 | 功能介绍 |
---|---|
static long currentTimeMillis() | 返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差 |
3.2 Date类(java8之前)
-- java.util.Date
类主要用于描述特定的瞬间,也就是年月日时分秒,可以精确到毫秒。
常用的方法
方法声明 | 功能介绍 |
---|---|
Date() | 使用无参的方式构造对象,也就是当前系统时间 |
Date(long date) | 根据参数指定毫秒数构造对象, 参数为距离1970年1月1日0时0分0秒的毫秒数 |
long getTime() | 获取调用对象距离1970年1月1日0时0分0秒的毫秒数 |
void setTime(long time) | 设置调用对象为距离基准时间time毫秒的时间点 |
3.3 SimpleDateFormat类(java8之前)
-- java.text.SimpleDateFormat
类主要用于实现日期和文本之间的转换。
常用的方法
方法声明 | 功能介绍 |
---|---|
SimpleDateFormat() | 使用无参方式构造对象 |
SimpleDateFormat(String pattern) | 根据参数指定的模式来构造对象,模式主要有: y-年 M-月 d-日 H-时 m-分 s-秒 |
final String format(Date date) | 用于将日期类型转换为文本类型 |
Date parse(String source) | 用于将文本类型转换为日期类型 |
3.4 LocalDate类( Java8)
-- java.time.LocalDate
类主要用于描述年-月-日格式的日期信息,该类不表示时间和时区信息。
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalDate now() | 在默认时区中从系统时钟获取当前日期 |
3.5 LocalTime类( Java8)
-- java.time.LocalTime
类主要用于描述时间信息,可以描述时分秒以及纳秒。
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalTime now() | 从默认时区的系统时间中获取当前时间 |
static LocalTime now(ZoneId zone) | 获取指定时区的当前时间 |
3.6 DateTimeFormatter类( Java8)
-- java.time.format.DateTimeFormatter
类主要用于格式化和解析日期。
常用的方法
方法声明 | 功能介绍 |
---|---|
static DateTimeFormatter ofPattern(String pattern) | 根据参数指定的模式来获取对象 |
String format(TemporalAccessor temporal) | 将参数指定日期时间转换为字符串 |
TemporalAccessor parse(CharSequence text) | 将参数指定字符串转换为日期时间 |