Java常用类库不要求有很多思想上的东西,要求对其有很熟练的使用能力。常用类库就好比在生活中手艺人手中的工具,作为一个Java程序员我们也必须熟练掌握这些工具。
导航
- 一、java.util.Objects
- 二、java.lang.Math
- 三、java.util.Arrays
- 四、java.math.BigDecimal
- 五、java.util.Date
- 六、java.text.DateFormat
- java.text.SimpleDateFormat
- 七、java.util.Calendar
- 八、java.lang.System
- 九、java.lang.String(绝对重点)
- 1. String类介绍
- 2. String类常用构造方法
- 3. String类常用方法
- 4. StringBuffer、StringBuilder和String的主要区别
- 5. String类小测试
一、java.util.Objects
在JDK7
版本添加的一个工具类。Objects此类包含static
实用程序方法,用于操作对象或在操作前检查某些条件。 这些实用程序包括null
或null
方法,用于计算对象的哈希代码,返回对象的字符串,比较两个对象,以及检查索引或子范围值是否超出范围。
常用的方法:
变量和类型 | 方法 | 描述 |
static int | checkIndex(int index, int length) | 检查 index是否在 0 (含)到 length (不包括)范围内。 |
static | compare(T a, T b, Comparator<? super T> c) | 如果参数相同则返回0,否则返回 c.compare(a, b) 。 |
static boolean | equals(Object a, Object b) | 返回 true如果参数相等,彼此 false其他。 |
static int | hash(Object… values) | 为一系列输入值生成哈希码。 |
static int | hashCode(Object o) | 返回非的哈希码 null参数,0为 null的论点。 |
static boolean | isNull(Object obj) | 返回 true如果提供的参考是 null ,否则返回 false 。 |
static boolean | nonNull(Object obj) | 返回 true如果提供的参考是非 null否则返回 false 。 |
static | requireNonNull(T obj) | 检查指定的对象引用是否不是 null 。 |
static | requireNonNull(T obj, String message) | 检查指定的对象引用是否为null ,如果是,则抛出自定义的NullPointerException 。 |
static String | toString(Object o) | 返回调用的结果 toString对于非 null参数, "null"为 null的说法。 |
static String | toString(Object o, String nullDefault) | 如果第一个参数不是 null ,则返回在第一个参数上调用 toString的结果,否则返回第二个参数。 |
/**
* Objects工具类
*/
public class Demo1Objects {
public static void main(String[] args) {
Person p1 = null;
Person p2 = new Person();
// 发生空指针异常,null不能调用方法
//Syem.out.println(p1.equals(p2));
// 使用Objects工具类不会发生异常
System.out.println(Objects.equals(p1, p2));
// 判断参数是否是空,为空返回true
System.out.println(Objects.isNull(p1));
// 判断参数是否是空,为空则返回空指针异常类
System.out.println(Objects.requireNonNull(p1));
}
}
运行结果:
false
true
Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at Demo1Objects.main(Demo1Objects.java:19)
二、java.lang.Math
类Math包含用于执行基本数字运算的方法,例如基本指数,对数,平方根和三角函数。
常用的方法:
变量和类型 | 方法 | 描述 |
static double | abs(double a) | 返回 double值的绝对值。 |
static float | abs(float a) | 返回 float值的绝对值。 |
static int | abs(int a) | 返回 int值的绝对值。 |
static long | abs(long a) | 返回 long值的绝对值。 |
static int | addExact(int x, int y) | 返回其参数的总和,如果结果溢出 int则抛出异常。 |
static double | ceil(double a) | 返回大于或等于参数且等于数学整数的最小值(最接近负无穷大) double 。 |
static double | floor(double a) | 返回小于或等于参数且等于数学整数的最大值(最接近正无穷大) double 。 |
static double | max(double a, double b) | 返回两个 double值中较大的 double 。 |
static float | max(float a, float b) | 返回两个 float值中较大的 float 。 |
static int | max(int a, int b) | 返回两个 int值中较大的 int。 |
static long | max(long a, long b) | 返回两个 long值中较大的 long 。 |
static double | min(double a, double b) | 返回两个 double值中较小的 double 。 |
static float | min(float a, float b) | 返回两个 float值中较小的 float 。 |
static int | min(int a, int b) | 返回两个 int值中较小的 int。 |
static long | min(long a, long b) | 返回两个 long 值中较小的 long。 |
static double | random() | 返回带有正号的 double值,大于或等于 0.0且小于 1.0 。 |
static long | round(double a) | 返回与参数最接近的 long ,并将关系四舍五入为正无穷大。 |
static int | round(float a) | 返回与参数最接近的 int ,并将关系四舍五入为正无穷大。 |
/**
* Math
*/
public class Demo2Math {
public static void main(String[] args) {
// 求绝对值
System.out.println("-100求绝对值:"+Math.abs(-100));
// 求两数之间较小的值
System.out.println("100,200求两数之间较小的值:"+Math.min(100,200));
// 求两数之间较大的值
System.out.println("100,200求两数之间较大的值:"+Math.max(100,200));
// 四舍五入
System.out.println("5.5四舍五入正数:"+Math.round(5.5));
System.out.println("-5.5四舍五入负数:"+Math.round(-5.5)); // 四舍五入变成-5
System.out.println("-5.51四舍五入负数:"+Math.round(-5.51)); // 四舍五入变成-6
// 返回小于等于参数的最大整数(地板)
System.out.println("3.5取地板正数:"+Math.floor(3.5));
System.out.println("-3.5取地板负数:"+Math.floor(-3.5));
// 返回大于等于参数的最小整数(天花板)
System.out.println("3.5取天花板正数:"+Math.ceil(3.5));
System.out.println("-3.5取天花板负数:"+Math.ceil(-3.5));
}
运行结果:
-100求绝对值:100
100,200求两数之间较小的值:100
100,200求两数之间较大的值:200
5.5四舍五入正数:6
-5.5四舍五入负数:-5
-5.51四舍五入负数:-6
3.5取地板正数:3.0
-3.5取地板负数:-4.0
3.5取天花板正数:4.0
-3.5取天花板负数:-3.0
三、java.util.Arrays
该类包含用于操作数组的各种方法(例如排序和搜索)。 此类还包含一个静态工厂,允许将数组视为列表。
如果指定的数组引用为null
,则此类中的方法都抛出NullPointerException
,除非另有说明。
常用的方法:
变量和类型 | 方法 | 描述 |
static | asList(T… a) | 返回由指定数组支持的固定大小的列表。 |
static int | binarySearch(Object[] a, Object key) | 使用二进制搜索算法在指定的数组中搜索指定的对象。 |
static int | binarySearch(Object[] a, int fromIndex, int toIndex, Object key) | 使用二进制搜索算法搜索指定对象的指定数组范围。 |
static | binarySearch(T[] a, T key, Comparator<? super T> c) | 使用二进制搜索算法在指定的数组中搜索指定的对象。 |
static | binarySearch(T[] a, int fromIndex, int toIndex, T key, Comparator<? super T> c) | 使用二进制搜索算法搜索指定对象的指定数组范围。 |
static | copyOf(T[] original, int newLength) | 使用空值复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度。 |
static <T,U>T[] | copyOf(U[] original, int newLength, 类<? extends T[]> newType) | 使用空值复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度。 |
static boolean | equals(int[] a, int[] a2) | 如果两个指定的int数组彼此 相等 ,则返回 true 。 |
static void | fill(Object[] a, Object val) | 将指定的Object引用分配给指定的Objects数组的每个元素。 |
static int | hashCode(Object[] a) | 根据指定数组的内容返回哈希码。 |
static int | mismatch(Object[] a, Object[] b) | 查找并返回两个 Object数组之间第一个不匹配的索引,否则如果未找到不匹配则返回-1。 |
static int | mismatch(Object[] a, int aFromIndex, int aToIndex, Object[] b, int bFromIndex, int bToIndex) | 查找并返回指定范围内两个 Object数组之间第一个不匹配的相对索引,否则如果未找到不匹配则返回-1。 |
static void | sort(Object[] a) | 根据元素的自然排序 ,将指定的对象数组按升序排序。 |
static void | sort(Object[] a, int fromIndex, int toIndex) | 根据元素的自然排序 ,将指定对象数组的指定范围按升序排序。 |
static String | toString(Object[] a) | 返回指定数组内容的字符串表示形式。 |
/**
* Arrays工具类
*/
public class Demo3Arrays {
public static void main(String[] args) {
int[] arr = {8,9,1,3,4,2,5,6,7};
// 打印数组的内存地址
System.out.println("数组的内存地址:"+arr);
// 输出数组的内容 [1, 2, 3]
System.out.println("排序前");
System.out.println(Arrays.toString(arr));
// 数组排序(正序,从小到大)
Arrays.sort(arr);
System.out.println("排序后");
System.out.println(Arrays.toString(arr));
// 二分查找指定参数的下标(没有返回-1)
System.out.println("二分查找指定参数的下标4");
System.out.println(Arrays.binarySearch(arr,4));
// 数组扩容(输入数组,新的长度)
System.out.println("原本的长度");
System.out.println(arr.length); // 原本的长度
arr = Arrays.copyOf(arr, 15);
System.out.println("扩容后的长度");
System.out.println(arr.length); // 扩容后的长度
}
}
运行结果:
数组的内存地址:[I@6cd8737
排序前
[8, 9, 1, 3, 4, 2, 5, 6, 7]
排序后
[1, 2, 3, 4, 5, 6, 7, 8, 9]
二分查找指定参数的下标4
3
原本的长度
9
扩容后的长度
15
四、java.math.BigDecimal
BigDecimal
类提供算术,比如操作,舍入,比较,散列和格式转换的操作。 该toString()
方法提供的规范表示BigDecimal
。
常用构造方法:
构造器 | 描述 |
BigDecimal(String val) | 将 BigDecimal的字符串表示 BigDecimal转换为 BigDecimal 。 |
BigDecimal(String val, MathContext mc) | 将 BigDecimal的字符串表示 BigDecimal转换为 BigDecimal ,接受与 BigDecimal(String)构造函数相同的字符串,并根据上下文设置进行舍入。 |
BigDecimal(int val) | 将 int翻译成 BigDecimal 。 |
BigDecimal(int val, MathContext mc) | 将 int转换为 BigDecimal ,并根据上下文设置进行舍入。 |
常用的方法:
变量和类型 | 方法 | 描述 |
BigDecimal | abs() | 返回 BigDecimal其值是此的绝对值 BigDecimal ,其标为 this.scale() 。 |
BigDecimal | add(BigDecimal augend) | 返回 BigDecimal其值为 (this + augend) ,其比例为 max(this.scale(), augend.scale()) 。 |
BigDecimal | divide(BigDecimal divisor) | 返回BigDecimal其值为(this / divisor) ,其首选比例为(this.scale() - divisor.scale()) ; 如果无法表示准确的商(因为它具有非终止的十进制扩展),则抛出ArithmeticException 。 |
double | doubleValue() | 将 BigDecimal转换为 double 。 |
int | intValue() | 将 BigDecimal转换为 int。 |
long | longValue() | 将 BigDecimal转换为 long。 |
float | float() | 将 BigDecimal转换为 float。 |
BigDecimal | multiply(BigDecimal multiplicand) | 返回 BigDecimal其值为 (this × multiplicand) ,其比例为 (this.scale() + multiplicand.scale()) 。 |
BigDecimal | subtract(BigDecimal subtrahend) | 返回 BigDecimal其值为 (this - subtrahend) ,其比例为 max(this.scale(), subtrahend.scale()) 。 |
/**
* BigDecimal
*/
public class Demo4BigDecimal {
public static void main(String[] args) {
// double类型和float类型运算会失去精度
System.out.println(0.1+0.2);
BigDecimal b1 = new BigDecimal("0.1"); // 传入的是String类型
BigDecimal b2 = new BigDecimal("0.2");
// b1,b2本身没有任何改变,等同于 b1+b2
BigDecimal b3 = b1.add(b2); // 加法运算
System.out.println(b1.subtract(b2)); // 减法运算
System.out.println(b1.multiply(b2)); // 乘法运算
System.out.println(b1.divide(b2)); // 除法运算
double d = b3.doubleValue(); // 变成double类型
int i = b3.intValue(); // 变成int类型
}
}
运行结果:
0.30000000000000004
-0.1
0.02
0.5
五、java.util.Date
Date
类表示特定的时刻,精度为毫秒。 (1秒=1000毫秒)
常用构造方法:
构造器 | 描述 |
Date() | 分配 Date对象并对其进行初始化,使其表示分配时间,测量 Date到毫秒。 |
Date(long date) | 分配 Date对象并初始化它以表示自标准基准时间(称为“纪元”)以来的指定毫秒数,即1970年1月1日00:00:00 GMT。 |
常用的方法:
变量和类型 | 方法 | 描述 |
boolean | after(Date when) | 测试此日期是否在指定日期之后。 |
boolean | before(Date when) | 测试此日期是否在指定日期之前。 |
Object | clone() | 返回此对象的副本。 |
int | compareTo(Date anotherDate) | 用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。 |
boolean | equals(Object obj) | 比较两个相等的日期。 |
static Date | from(Instant instant) | 从 Instant对象获得 Date的实例。 |
int | hashCode() | 返回此对象的哈希码值。 |
long | getTime() | 返回自此 Date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。 |
void | setTime(long time) | 将此 Date对象设置为表示格林尼治标准时间1970年1月1日00:00:00之后的 time毫秒的时间点。 |
Instant | toInstant() | 将此 Date对象转换为 Instant 。 |
String | toString() | 将此 Date对象转换为以下形式的 String 。 |
/**
* Date类表示特定的时刻,精度为毫秒。
*/
public class Demo5Date {
public static void main(String[] args) {
// 创建一个当前时间的Date
Date date = new Date();
// 打印Date类的toString方法
System.out.println("当前日期:"+date);
// 计算当前日期减一天
long time = date.getTime()-(24*60*60*1000);
Date date2 = new Date(time);
System.out.println("当前日期减一天:"+date2);
}
}
运行结果:
当前日期:Sun Dec 27 15:00:47 CST 2020
当前日期减一天:Sat Dec 26 15:00:47 CST 2020
六、java.text.DateFormat
DateFormat
是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化和分析日期或时间。 日期/时间格式化子类(例如SimpleDateFormat
)允许格式化(即,日期→文本),解析(文本“日期”)和规范化。 日期表示为Date对象或自1970年1月1日00:00:00 GMT以来的毫秒数。
java.text.SimpleDateFormat
DateFormat
是一个抽象类不能直接使用,想要使用需要使用它的子类SimpleDateFormat
。SimpleDateFormat
是一个用于以区域设置敏感的方式格式化和解析日期的具体类。 它允许格式化(日期→文本),解析(文本→日期)和规范化。
常用构造方法:
构造器 | 描述 |
SimpleDateFormat() | 构造一个 SimpleDateFormat使用默认模式和日期格式符号默认 FORMAT区域设置。 |
SimpleDateFormat(String pattern) | 构造一个 SimpleDateFormat使用给定的模式和默认的默认日期格式符号 FORMAT区域设置。 |
SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols) | 使用给定的模式和日期格式符号构造 SimpleDateFormat 。 |
SimpleDateFormat(String pattern, Locale locale) | 使用给定模式和给定语言环境的默认日期格式符号构造 SimpleDateFormat 。 |
常用的方法:
变量和类型 | 方法 | 描述 |
boolean | equals(Object obj) | 比较给定对象与此 SimpleDateFormat是否相等。 |
StringBuffer | format(Date date, StringBuffer toAppendTo, FieldPosition pos) | 将给定的 Date为日期/时间字符串,并将结果附加到给定的 StringBuffer 。 |
Date | parse(String text, ParsePosition pos) | 解析字符串中的文本以生成 Date 。 |
String | toPattern() | 返回描述此日期格式的模式字符串。 |
/**
* DateFormat
*/
public class Demo6DateFormat {
public static void main(String[] args) throws ParseException {
/**
* y:年
* M:月
* d:日
* H:时
* m:分
* s:秒
*/
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
// format:将Date对象转换成字符串("yyyy年MM月dd日 HH:mm:ss")
String text = format.format(new Date());
System.out.println(text);
// parse:将("yyyy年MM月dd日 HH:mm:ss")日期字符串,转换为date对象
Date parse = format.parse("2022年11月11日 16:45:36");
// 今天离2022年11月11日还有几天
System.out.println((parse.getTime()-new Date().getTime())/1000/60/60/24);
}
}
运行结果:
2020年12月27日 16:40:02
684
七、java.util.Calendar
Calendar
类是一个抽象类,可以为在某一特定时刻和一组之间的转换的方法calendar fields如YEAR
, MONTH
, DAY_OF_MONTH
, HOUR
,等等,以及用于操纵该日历字段,如获取的日期下个星期。 瞬间可以用毫秒值表示,该值是1970年1月1日格林威治标准时间1970年1月1日00:00:00,000(格里高利)的Epoch的偏移量。Calendar
提供了一个类方法getInstance
,用于获取此类型的通用对象。 Calendar
的getInstance
方法返回一个Calendar
对象,其日历字段已使用当前日期和时间初始化:
Calendar rightNow = Calendar.getInstance();
常用的字段汇总:
变量和类型 | 字段 | 描述 |
static int | AM | AM_PM字段的值,表示从午夜到正午之前的一天的时段。 |
static int | AM_PM | get和 set字段编号表示 HOUR是在中午之前还是之后。 |
static int | DATE | get和 set字段编号表示当月的日期。 |
static int | DAY_OF_MONTH | get和 set字段编号表示当月的日期。 |
static int | DAY_OF_WEEK | 字段编号为 get和 set表示星期几。 |
static int | DAY_OF_WEEK_IN_MONTH | get和 set字段编号,表示当前月份中某一天的序号。 |
static int | DAY_OF_YEAR | get和 set字段编号表示当年的日期编号。 |
static int | FRIDAY | DAY_OF_WEEK字段的值表示星期五。 |
static int | HOUR | get和 set字段编号表示上午或下午的小时。 |
static int | HOUR_OF_DAY | get和 set字段编号表示当天的小时。 |
static int | MILLISECOND | get和 set字段编号表示秒内的毫秒数。 |
static int | MINUTE | get和 set字段编号表示小时内的分钟。 |
static int | MONTH | get和 set字段编号表示月份。 |
protected long | time | 此日历的当前设置时间,以1970年1月1日格林威治标准时间0:00:00之后的毫秒数表示。 |
static int | WEEK_OF_MONTH | get和 set字段编号, get set的周数。 |
static int | WEEK_OF_YEAR | get和 set字段编号表示当前年份的周数。 |
static int | YEAR | 字段编号为 get和 set表示年份。 |
常用的方法:
变量和类型 | 方法 | 描述 |
abstract void | add(int field, int amount) | AM_PM字段的值,表示从午夜到正午之前的一天的时段。 |
boolean | after(Object when) | 返回此 Calendar是否表示指定的 Object表示的时间之后的时间。 |
boolean | before(Object when) | 返回此 Calendar是否表示指定的 Object代表的时间之前的时间。 |
int | get(int field) | 返回给定日历字段的值。 |
int | getActualMaximum(int field) | 给定此 Calendar的时间值,返回指定日历字段可能具有的 Calendar 。 |
int | getActualMinimum(int field) | 给定此 Calendar的时间值,返回指定日历字段可能具有的 Calendar 。 |
int | getFirstDayOfWeek() | 得到一周的第一天是什么; 例如, SUNDAY在美国, MONDAY在法国。 |
static Calendar | getInstance() | 使用默认时区和区域设置获取日历。 |
Date | getTime() | 返回一个 Date对象,表示此 Calendar的时间值(距离 Epoch的毫秒偏移量)。 |
long | getTimeInMillis() | 以毫秒为单位返回此Calendar的时间值。 |
TimeZone | getTimeZone() | 获取时区。 |
void | set(int field, int value) | 将给定的日历字段设置为给定值。 |
void | setTime(Date date) | 使用给定的 Date设置此日历的时间。 |
String | toString() | 返回此日历的字符串表示形式。 |
/**
* Calendar日历类
*/
public class Demo7Calendar {
// get
// set
// add
// getTime:获取日历时间,表示的Date对象
// getActualMaxmum:获取某字段的最大值
public static void main(String[] args) {
// Calender是一个抽象类不能直接new,使用getInstance()会帮你返回一个已经实现好的一个子类对象,基于不同地区所编写的
Calendar cl = Calendar.getInstance();
// 获取日历里的年份
int year = cl.get(Calendar.YEAR);
System.out.println("日历里的年份:"+year);
// 获取日历里的天数
int day = cl.get(Calendar.DAY_OF_YEAR); // 根据年
System.out.println("日历里的天数:"+day);
System.out.println("获取今天是当前月份的第几天:"+cl.get(Calendar.DAY_OF_MONTH)); // 根据月份
System.out.println("根据星期:"+cl.get(Calendar.DAY_OF_WEEK)); // 根据星期
System.out.println("根据周和月:"+cl.get(Calendar.DAY_OF_WEEK_IN_MONTH)); // 根据周和月
// 设置日历中的年份为2022年
cl.set(Calendar.YEAR,2022);
System.out.println("日历中的年份为2022年:"+cl.get(Calendar.YEAR));
// 获取日历里的星期数
System.out.println("根据年获取日历里的星期数:"+cl.get(Calendar.WEEK_OF_YEAR)); // 根据年
// 年份加1,减法就是加负数
cl.add(Calendar.YEAR,1);
System.out.println("年份加1:"+cl.get(Calendar.YEAR));
// 在计算机中月份是 0-11
// 月份减5
cl.add(Calendar.MONTH,-5);
System.out.println("月份减5:"+cl.get(Calendar.MONTH));
// 获取日历时间,表示的Date对象
Date time = cl.getTime();
// 获取当前年的最大月份
int m = cl.getActualMaximum(Calendar.MONTH);
System.out.println("获取当前年的最大月份:"+m);
// 获取当前年的最大天数
int d = cl.getActualMaximum(Calendar.DAY_OF_YEAR);
System.out.println("当前年的最大天数:"+d);
// 获取指定月份的天数
cl.set(Calendar.MONTH,1);
System.out.println("获取2月份的天数:"+cl.getActualMaximum(Calendar.DAY_OF_MONTH));
// 获取一年中有多少周
System.out.println("获取一年中有多少周:"+cl.getActualMaximum(Calendar.WEEK_OF_YEAR));
}
}
运行结果:
日历里的年份:2020
日历里的天数:362
获取今天是当前月份的第几天:27
根据星期:1
根据周和月:4
日历中的年份为2022年:2022
根据年获取日历里的星期数:53
年份加1:2023
月份减5:6
获取当前年的最大月份:11
当前年的最大天数:365
获取2月份的天数:28
获取一年中有多少周:52
八、java.lang.System
System
类包含几个有用的类字段和方法。 它无法实例化。 System
类提供的设施包括标准输入,标准输出和错误输出流; 访问外部定义的属性和环境变量; 加载文件和库的方法; 以及用于快速复制阵列的一部分的实用方法。
常用的字段汇总:
System类的字段是一定要清楚的
变量和类型 | 字段 | 描述 |
static PrintStream | err | “标准”错误输出流。 |
static InputStream | in | “标准”输入流。 |
static PrintStream | out | “标准”输出流。 |
常用的方法:
变量和类型 | 方法 | 描述 |
static void | arraycopy(Object src, int srcPos, Object dest, int destPos, int length) | 将指定源数组中的数组从指定位置开始复制到目标数组的指定位置。 |
static long | currentTimeMillis() | 以毫秒为单位返回当前时间。 |
static Console | console() | 返回与当前Java虚拟机关联的唯一Console对象(如果有)。 |
static void | exit(int status) | 终止当前运行的Java虚拟机。 |
static void | gc() | 运行垃圾收集器。 |
static Properties | getProperties() | 确定当前系统属性。 |
static String | getProperty(String key) | 获取指定键指示的系统属性。 |
九、java.lang.String(绝对重点)
写Java代码那么久,可以发现,使用String
可以表示出一个字符串,但是使用此类的时候也会发现有一点问题。
从String
命名风格可以发现,String
是一个类,但是此类在使用的时候却发现可以不用构造方法而直接赋值,很多人初学者刚开始认为String
是一个基本数据类型,这是一个误区。那么String
类这样的操作有哪些特点呢?
1. String类介绍
String
类表示字符串(在 Java 中字符串属于对象)。 Java程序中的所有字符串文字(例如"abc" )都实现为此类的实例。
字符串是不变的; 它们的值在创建后无法更改。 字符串缓冲区支持可变字符串。 因为 String
对象是不可变的,所以可以共享它们。 例如:
String str = "abc";
相当于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
2. String类常用构造方法
构造器 | 描述 |
String() | 初始化新创建的 String对象,使其表示空字符序列。 |
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组构造新的 String 。 |
String(byte[] bytes, String charsetName) | 构造一个新的String由指定用指定的字节的数组解码charset 。 |
String(char[] value) | 分配新的 String ,使其表示当前包含在字符数组参数中的字符序列。 |
String(String original) | 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本。 |
String(StringBuffer buffer) | 分配一个新字符串,其中包含当前包含在字符串缓冲区参数中的字符序列。 |
String(StringBuilder builder) | 分配一个新字符串,其中包含当前包含在字符串构建器参数中的字符序列。 |
3. String类常用方法
记录了在Java开发时使用String
类可能用得到的方法
变量和类型 | 方法 | 描述 |
char | charAt(int index) | 返回指定索引处的 char值。 |
int | codePointAt(int index) | 返回指定索引处的字符(Unicode代码点)。 |
int | codePointBefore(int index) | 返回指定索引之前的字符(Unicode代码点)。 |
int | codePointCount(int beginIndex, int endIndex) | 返回此 String的指定文本范围内的Unicode代码点数。 |
int | compareTo(String anotherString) | 按字典顺序比较两个字符串。 |
boolean | contains(CharSequence s) | 当且仅当此字符串包含指定的char值序列时,才返回true。 |
static String | copyValueOf(char[] data) | 相当于 valueOf(char[]) 。 |
boolean | startsWith(String prefix) | 测试此字符串是否以指定的前缀开头。 |
boolean | endsWith(String suffix) | 测试此字符串是否以指定的后缀结尾。 |
boolean | equals(Object anObject) | 将此字符串与指定的对象进行比较。 |
boolean | equalsIgnoreCase(String anotherString) | 将此 String与另一个 String比较,忽略了大小写。 |
int | hashCode() | 返回此字符串的哈希码。 |
int | indexOf(String str) | 返回指定子字符串第一次出现的字符串中的索引。 |
int | indexOf(String str, int fromIndex) | 从指定的索引处开始,返回指定子字符串第一次出现的字符串中的索引。 |
int | lastIndexOf(String str) | 返回指定子字符串最后一次出现的字符串中的索引。 |
int | lastIndexOf(String str, int fromIndex) | 返回指定子字符串最后一次出现的字符串中的索引,从指定索引开始向后搜索。 |
String | intern() | 返回字符串对象的规范表示。 |
boolean | isEmpty() | 返回 true ,当且仅当, length()是 0 。 |
int | length() | 返回此字符串的长度。 |
String | replace(char oldChar, char newChar) | 返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar 。 |
String | replaceAll(String regex, String replacement) | 将给定替换的给定 正则表达式匹配的此字符串的每个子字符串替换。 |
String | replaceFirst(String regex, String replacement) | 将给定替换的给定 正则表达式匹配的此字符串的第一个子字符串替换。 |
String[] | split(String regex) | 将此字符串拆分为给定 正则表达式的匹配 项 。 |
boolean | matches(String regex) | 判断此字符串是否与给定的 正则表达式匹配。 |
String | substring(int beginIndex) | 返回一个字符串,该字符串是此字符串的子字符串。 |
String | substring(int beginIndex, int endIndex) | 返回一个字符串,该字符串是此字符串的子字符串。 |
char[] | toCharArray() | 将此字符串转换为新的字符数组。 |
String | toLowerCase() | 使用默认语言环境的规则将此 String所有字符转换为小写。 |
String | toUpperCase() | 使用默认语言环境的规则将此 String所有字符转换为大写。 |
String | trim() | 返回一个字符串,其值为此字符串,删除了所有前导和尾随空格,其中space被定义为其代码点小于或等于 ‘U+0020’ (空格字符)的任何字符。 |
static String | valueOf(Object obj) | 返回 Object参数的字符串表示形式。 |
以下是一些如何使用字符串的示例:
/**
1. String
2. 字符串是不变的
3. 它们的值在创建后无法更改。
4. 字符串缓冲区支持可变字符串。
5. 因为String对象是不可变的,所以可以共享它们
*/
public class DemoString {
public static void main(String[] args) {
String text1 = "123"; // String直接创建
String text2 = "123"; // String直接创建
// new表示新开辟的空间(不会被缓存起来),内存地址绝对不可能相同,哪怕内容一样
String text3 = new String("123"); // String对象创建
System.out.println(text1 == text2);
System.out.println(text1 == text3);
// substring下标包含开始不包含结尾
System.out.println("123456".substring(2, 5));
// 字符串拼接,有几个加号就产生几个内存垃圾(能避免尽量避免)
// 如果使用字符串拼接,不应该使用String
// 应该使用StringBuffer,StringBuilder(可变字符序列,更节省内存)
text1 = text1 + text2 + text3;
System.out.println(text1);
// StringBuilder 线程不安全的实现
// StringBuffer 线程安全的实现
StringBuilder sb = new StringBuilder("hahaha");
sb.append("666");
System.out.println(sb.toString());
}
}
运行结果:
true
false
345
123123123
hahaha666
解析:
- 由于
String
字符串的不可变性,常量池中一定不存在两个相同的字符串。所以text1 == text2
是true
。 -
new String("123");
时,new表示新开辟的空间(不会被缓存起来),内存地址绝对不可能相同,哪怕内容一样。 - 使用"+"进行字符串拼接,有几个加号就产生几个内存垃圾(能避免尽量避免)。如果想要字符串拼接,不应该使用
String
应该使用StringBuffer
,StringBuilder
(可变字符序列,更节省内存)。
4. StringBuffer、StringBuilder和String的主要区别
-
String
是不可变字符序列,StringBuilder
和StringBuffer
是可变字符序列。 - 执行速度
StringBuilder
>StringBuffer
>String
。 -
StringBuilder
是非线程安全的,StringBuffer
是线程安全的。
5. String类小测试
String类是我们在开发中使用频率最高的类之一,也是在面试时极有可能会被问到的,下面是一道测试题:
public class TestString {
public static void main(String[] args) {
String s1 = "1234"; // 双引号直接创建出来的String对象会直接存储在字符串常量池中
String s2 = new String("1234"); // String对象创建
System.out.println(s1 == s2); // new是新创建的对象,不在字符串常量池中,所以是false
String s3 = "12" + "34";
// 字符串的+操作其本质是创建了StringBuilder对象进行append操作
// 然后将拼接后的StringBuilder对象用toString方法处理成String对象,所以是true
System.out.println(s1 == s3);
String s4 = "12";
String s5 = "34";
String s6 = s4 + s5;
System.out.println(s1 == s6); // s6不在字符串常量池中,所以是false
// String对象的intern方法会得到字符串对象在常量池中对应的引用
// 如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用
System.out.println(s1 == s6.intern()); // s6被添加到常量池中了,所以是true
System.out.println(s2 == s2.intern()); // s2在堆中,s2.intern()在常量池中,所以是false
}
}
运行结果:
false
true
false
true
false
在解析前必须要知道的点:
- 双引号直接创建出来的String对象会直接存储在堆内存中的字符串常量池中,
new String()
表示新开辟的空间,不会放在常量池中,而是放在存储在堆内存中。 - 字符串的"+"操作其本质是创建了
StringBuilder
对象进行append()
操作,然后将拼接后的StringBuilder
对象用toString()
方法处理成String对象。 - String对象的
intern()
方法会得到字符串对象在常量池中对应的引用,如果常量池中没有对应的字符串,则该字符串将被添加到常量池中,然后返回常量池中字符串的引用。
解析:
-
String s1 = "1234";
是直接在字符串常量池中创建了"1234"字符串,String s2 = new String("1234");
是在堆内存中创建了String
对象,它们的引用不相同,所以s1 == s2
为false
。 -
String s3 = "12" + "34";
它们相加必然是"1234"字符串,与String s1 = "1234";
的内容是一样的,因此无需再在常量池中创建"1234"字符串,而是直接把"1234"字符串的引用地址赋予s3
,所以s1 == s3
是true
。 -
String s6 = s4 + s5;
这里是对象的相加,虽然s6
的值是"1234",但是因为是对象的相加,所以s6
存储在堆内存中并且是新开辟的空间,所以s1 == s6
为false
。 -
s6.intern()
因为s6
是存储在堆内存空间中,不在常量池内,因此执行intern()
会把s6
添加到字符串常量池中,又因为s6
的内容为"1234"与String s1 = "1234";
相同,所以会直接把"1234"字符串的引用地址赋予s6
,所以s1 == s6.intern()
是true
。 -
s2 == s2.intern()
,s2
存储在堆内存中,s2.intern()
会被添加到字符串常量池中,因此这句话也等同于s2 == s1
,所以s2 == s2.intern()
为false
。