Java 中的 System
类是 Java 标准库的一部分,它属于 java.lang
包,因此在使用时不需要显式地导入。这个类提供了一些与系统相关的功能,主要包括以下几个方面:
- 标准输入输出:
System.in
:标准输入流,通常用于从键盘读取数据。System.out
:标准输出流,用于向控制台打印信息。System.err
:标准错误流,用于打印错误信息。
- 环境变量:
System.getenv(String name)
:获取指定的环境变量值。
- 属性:
System.getProperties()
:获取系统属性集合。System.getProperty(String key)
:根据键获取系统属性的值。
- 时间:
System.currentTimeMillis()
:返回当前时间的毫秒数,从1970年1月1日00:00:00 GMT开始计算。
- 垃圾回收:
System.gc()
:建议运行垃圾回收器。
- 退出程序:
System.exit(int status)
:终止当前运行的Java虚拟机。参数status
通常用来表示程序的退出状态。
- 数组复制:
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
:将一个数组的一部分复制到另一个数组。
- 运行时信息:
System.nanoTime()
:返回当前时间的纳秒数,用于测量短时间间隔。
- 安全管理器:
System.getSecurityManager()
:获取当前的安全管理器,如果没有设置则返回null
。
这些是 System
类中一些常用的方法和属性。使用 System
类可以方便地进行一些系统级的操作,但要注意,频繁地使用 System.out
或 System.err
打印信息可能会影响程序的性能。此外,使用 System.exit()
退出程序是一种比较粗暴的方式,通常在应用程序中使用异常处理机制来优雅地结束程序。
Java 中的 Runtime
类是 java.lang
包的一部分,用于与运行时环境进行交互。这个类提供了一些方法来控制运行时环境,例如执行垃圾回收、获取系统属性、退出程序等。以下是一些 Runtime
类的常用方法:
- 获取运行时对象:
Runtime runtime = Runtime.getRuntime();
:获取当前Java应用程序的运行时对象。
- 执行垃圾回收:
runtime.gc()
:建议Java虚拟机(JVM)执行垃圾回收。注意,这只是一个建议,JVM可以选择忽略。
- 获取可用处理器数量:
runtime.availableProcessors()
:返回运行时环境的可用处理器数量。
- 获取和设置最大内存:
runtime.maxMemory()
:返回JVM尝试使用的最大内存量。runtime.totalMemory()
:返回JVM使用的内存总量,包括已使用的和未使用的内存。
- 自由内存:
runtime.freeMemory()
:返回JVM当前空闲的内存量。
- 退出程序:
runtime.exit(int status)
:终止当前运行的JVM。参数status
通常用来表示程序的退出状态。注意,这个调用将立即结束JVM,不会执行任何清理操作。
- 加载库:
runtime.load(String filename)
:加载指定的库文件。
- 加载库并指定路径:
runtime.loadLibrary(String libname)
:从库搜索路径中加载具有指定名称的库。
- 添加关闭钩子:
runtime.addShutdownHook(Thread hook)
:在JVM关闭时运行的钩子线程。
- 跟踪内存使用:
runtime.traceInstructions(boolean on)
:启用或禁用指令跟踪。runtime.traceMethodCalls(boolean on)
:启用或禁用方法调用跟踪。
Runtime
类提供了一些非常有用的功能,特别是在需要对JVM进行一些底层控制时。然而,由于JVM的内存管理是自动的,通常不需要手动调用 gc()
方法,因为JVM的垃圾回收器会自动进行内存管理。同样,使用 exit()
方法来终止程序应该谨慎,因为它不会给运行的线程机会来清理和保存状态。
字符串常量池 String 字符长度不变
字符串中直接使用双引号包裹的字符串就在常量池中,字符串常量池存在于堆当中,常量池中的字符串可以共享。字符串常量池的主要目的是优化程序的性能和内存使用。
// 1.常量池:双引号直接包裹着的字符串是在常量池中的。
// 2.==在基本数据类型中是对值的进行比较,在引用型数据类型中时是对地址值的比较。
public class StringPool{
public static void main(String[] args){
String str1 = "123";
String str2 = "123";
char[] chararr = {'1','2','3'};
String str3 = new String(chararr);
System.out.println(str1 == str2);//true,表明str1和str2的地址值相同
System.out.println(str1 == str3);//false,表明str1和str3的地址值不相同
System.out.println(str2 == str3);//false,表明str2和str2的地址值不相同
}
}
常见方法
-
创建字符串:
javaString str = "Hello, World!"; String name = new String("John Doe");
-
连接字符串:
javaString greeting = "Hello"; String message = greeting + ", " + name; // "Hello, John Doe"
-
获取字符串长度:
java int length = str.length(); // 获取字符串"Hello, World!"的长度
-
访问字符串中的字符:
java char charAtIndex = str.charAt(0); // 获取字符串第一个字符,即'H'
-
字符串比较:
java boolean isEqual = str.equals("Hello, World!"); // 比较字符串内容是否相同
-
查找子字符串:
java int index = str.indexOf("World"); // 查找子字符串"World"的索引
-
字符串替换:
java String replaced = str.replace("World", "Earth"); // 将"World"替换为"Earth"
-
字符串分割:
java String[] parts = str.split(", "); // 以", "为分隔符分割字符串
-
字符串转换为大写或小写:
javaString upper = str.toUpperCase(); // 转换为大写 String lower = str.toLowerCase(); // 转换为小写
-
去除字符串首尾的空白:
java String trimmed = str.trim(); // 去除字符串两端的空格
String
类提供的方法非常多,可以满足各种字符串操作的需求。由于String
对象是不可变的,对字符串的任何修改实际上都会创建一个新的String
对象。这也意味着String
类在多线程环境中是线程安全的。
正则表达式
String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
String[] split(String regex): 根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit): 根据匹配给定的正则表达式来拆分此字符串。
###### 正则表达式
负责字符串的匹配处理(一般用于校验字符串格式)
规则
- 字符
- x:x字符,a表a字符
- \:反斜线字符
- \n:换行符
- \r:回车符
- 字符类
- [abc]:表示a、b、c中的一个字符
- [^abc]:表示除了a、b、c之外的任意一个字符
- [a-zA-Z]:表示az或AZ中的一个字符
- [0-9]:表示数字
- 预定义字符类
- .:表示任意字符
- .:表示'.'字符
- \d:表示数字字符,[0-9]
- \w:表示单词字符,[a-zA-Z_0-9]
- 边界匹配器
- ^:表示行的开头
- $:表示行的结尾
- \b:表示单词的边界
- 数量词
- ?:表示0次或者1次
- *:表示0次或者多次
- +:表示1次或者多次
- {n}:表示n次
- {n,}:表示至少n次
- {n,m}:n~m次
SpringBuffer和Spring Builder
StringBuilder类
线程不安全的可变字符序列
1)构造方法
StringBuilder():以默认容量创建空的StringBuilder对象
StringBuilder(int capacity):以指定容量创建空的StringBuilder对象
StringBuilder(String str):以指定的字符串创建StringBuilder对象
2)成员方法
获取功能
int capacity():获取容量
int length():获取长度
添加功能
append(int value):追加。可以追加多种类型
insert(int offset,String s):在指定的位置插入指定数据
删除功能
deleteCharAt(int index):删除指定索引处的元素
delete(int start,int end):删除[start,start-1]范围内的元素
替换功能
replace(int start,int end,String s):将[start,end-1]范围内的元素替换成指定字符串
反转功能
reverse():元素反转
截取功能
String subString(int start):截取指定位置一直到末尾
String subString(int start,int end):截取[start,end-1]范围
String、StringBuilder和StringBuffer的区别?
String内容不可改变
StringBuilder和StringBuffer内容可变
StringBuilder是线程不安全的,不同步,效率高
StringBuffer是线程安全的,同步,效率低
-
StringBuffer
与StringBuilder
类似,但它是线程安全的。这意味着它内部的修改操作是同步的,可以在多线程环境中使用,但性能略低于StringBuilder
。 -
使用
StringBuffer
进行字符串连接的例子:
javaStringBuffer sb = new StringBuffer(); for (int i = 0; i < 100; i++) { sb.append("Hello "); } String result = sb.toString();
-
线程安全:
StringBuffer
是线程安全的,这意味着多个线程可以同时访问同一个StringBuffer
对象,而不会导致数据不一致的问题。
-
同步:
- 为了实现线程安全,
StringBuffer
的方法都是同步的(使用synchronized
关键字)。
- 为了实现线程安全,
-
使用场景:
- 当你在多线程环境中需要修改字符串时,
StringBuffer
是一个合适的选择。
- 当你在多线程环境中需要修改字符串时,
-
性能:
- 由于同步带来的开销,
StringBuffer
在单线程环境下的性能通常不如StringBuilder
。
- 由于同步带来的开销,
-
方法:
-
StringBuffer
提供了多种方法来操作字符串,包括:
append()
:追加字符串或对象。insert()
:在指定位置插入字符串或对象。delete()
或deleteCharAt()
:删除指定位置的字符或子字符串。replace()
:替换指定范围内的字符。reverse()
:反转字符串。- 等等。
-
-
容量自动扩展:
- 当向
StringBuffer
中添加字符时,如果超出当前容量,它会根据需要自动扩展。
- 当向
-
转换为String:
- 可以通过调用
StringBuffer
的toString()
方法来获取一个不可变的String
对象。
- 可以通过调用
-
示例代码:
java复制StringBuffer sb = new StringBuffer("Hello"); sb.append(" World"); sb.insert(5, " beautiful "); System.out.println(sb.toString()); // 输出: Hello beautiful World
Data类 日期时间
ava.util.Date
类表示特定的瞬间,精确到毫秒。Date类的构造函数可以把毫秒值转成日期对象。
构造方法:
public Date():分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
public Date(long date):分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即1970年1月1日00:00:00 GMT)以来的指定毫秒数。
Simple DataFormat 格式化
DateFormat类
java.text.DateFormat 是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。
格式化:按照指定的格式,从Date对象转换为String对象。(format)
解析:按照指定的格式,从String对象转换为Date对象。(parse)
2.1 其子类SimpleDateFormat的构造方法
由于DateFormat为抽象类,不能直接使用,所以需要常用的子类java.text.SimpleDateFormat。这个类需要一个模式(格式)来指定格式化或解析的标准。构造方法为:
public SimpleDateFormat(String pattern):用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。
参数pattern是一个字符串,代表日期时间的自定义格式。
Calendar类
Calendar
类是 Java 中的一个抽象类,位于 java.util
包中,用于表示和操作日期和时间。Calendar
类本身不包含日期信息,而是作为各种具体日历系统的抽象,例如 GregorianCalendar
。以下是 Calendar
类的一些关键特性和用法:
- 抽象类:
Calendar
是一个抽象类,不能直接实例化。你需要使用其子类,如GregorianCalendar
。
- 字段常量:
Calendar
类定义了一系列的字段常量,表示日期的不同部分,例如YEAR
、MONTH
、DAY_OF_MONTH
、HOUR_OF_DAY
等。
- 获取实例:
- 可以通过
Calendar.getInstance()
方法获取Calendar
对象的实例,它将使用默认的时区和语言环境。
- 可以通过
- 设置和获取日期时间:
- 使用
set(int field, int value)
方法设置日期时间的特定字段。 - 使用
get(int field)
方法获取日期时间的特定字段值。
- 使用
- 日期时间计算:
- 使用
add(int field, int amount)
方法对日期时间进行增减操作。
- 使用
- 比较日期时间:
- 使用
before(Object when)
和after(Object when)
方法比较两个日期时间。
- 使用
- 清除字段:
- 使用
clear()
方法清除当前Calendar
对象的日期时间设置。
- 使用
- 时间戳:
- 使用
getTime()
和setTime(Date date)
方法与Date
对象进行交互。
- 使用
- 时区处理:
- 可以使用
getTimeZone()
和setTimeZone(TimeZone zone)
方法处理时区。
- 可以使用
- 实例化特定日历:
- 例如,使用
new GregorianCalendar()
创建公历的实例。
- 例如,使用
示例代码:
javaimport java.util.Calendar;
import java.util.TimeZone;
public class CalendarExample {
public static void main(String[] args) {
// 获取默认时区的Calendar实例
Calendar calendar = Calendar.getInstance();
// 设置日期和时间
calendar.set(2024, Calendar.AUGUST, 5, 15, 30); // 2024年8月5日 15:30
// 获取年份
int year = calendar.get(Calendar.YEAR);
// 输出年份
System.out.println("Year: " + year);
// 更改时区
calendar.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// 获取并输出当前时间
System.out.println("Current Time: " + calendar.getTime());
}
}
```## Math类
![image-20240805164818211](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805164818211.png)
ava 中的 `Math` 类是 `java.lang` 包的一部分,提供了用于执行基本数学运算的静态方法。由于它属于 `java.lang` 包,所以在使用时不需要显式地导入。以下是 `Math` 类的一些常用方法和特性:
1. **基本数学运算**:
- `Math.abs(x)`:返回 `x` 的绝对值。
- `Math.sqrt(x)`:返回 `x` 的平方根。
- `Math.cbrt(x)`:返回 `x` 的立方根(Java 8及以上版本)。
2. **幂函数**:
- `Math.pow(x, y)`:返回 `x` 的 `y` 次幂。
- `Math.exp(x)`:返回 `e` 的 `x` 次幂。
- `Math.log(x)`:返回 `x` 的自然对数。
3. **三角函数**:
- `Math.sin(x)`:返回 `x` 的正弦值,`x` 以弧度为单位。
- `Math.cos(x)`:返回 `x` 的余弦值,`x` 以弧度为单位。
- `Math.tan(x)`:返回 `x` 的正切值,`x` 以弧度为单位。
4. **双曲函数**:
- `Math.sinh(x)`:返回 `x` 的双曲正弦值。
- `Math.cosh(x)`:返回 `x` 的双曲余弦值。
- `Math.tanh(x)`:返回 `x` 的双曲正切值。
5. **角度和弧度转换**:
- `Math.toRadians(x)`:将角度 `x` 转换为弧度。
- `Math.toDegrees(x)`:将弧度 `x` 转换为角度。
6. **取整函数**:
- `Math.round(x)`:将 `x` 四舍五入到最接近的整数。
- `Math.floor(x)`:向下取整到最接近的整数。
- `Math.ceil(x)`:向上取整到最接近的整数。
7. **最大最小值**:
- `Math.max(x, y)`:返回 `x` 和 `y` 中的最大值。
- `Math.min(x, y)`:返回 `x` 和 `y` 中的最小值。
8. **随机数生成**:
- `Math.random()`:返回一个 `double` 值,它大于等于 0.0 且小于 1.0。
9. **常量**:
- `Math.PI`:圆周率的值。
- `Math.E`:自然对数的底数 `e`。
### 示例代码:
javapublic class MathExample {
public static void main(String[] args) {
// 计算绝对值
double absValue = Math.abs(-10.5);
// 计算平方根
double sqrtValue = Math.sqrt(16);
// 计算最大值
double maxValue = Math.max(10, 20);
// 生成随机数
double randomValue = Math.random();
// 打印结果
System.out.println("Absolute Value: " + absValue);
System.out.println("Square Root: " + sqrtValue);
System.out.println("Max Value: " + maxValue);
System.out.println("Random Value: " + randomValue);
}
}
`Math` 类提供了丰富的数学工具,可以满足大多数基本数学运算的需求。然而,对于更复杂的数学计算,可能需要使用其他专门的数学库,如 Apache Commons Math。
## 包装类特点
![image-20240805165331985](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165331985.png)
- -
## 基本数据类型与包装
- 基本类型与包装类:
- `boolean` 和 `Boolean`
- `byte` 和 `Byte`
- `short` 和 `Short`
- `int` 和 `Integer`
- `long` 和 `Long`
- `float` 和 `Float`
- `double` 和 `Double`
## 包装类共同点
![image-20240805165440427](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165440427.png)
## 自动装箱,拆箱
![image-20240805165544620](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165544620.png)
在Java中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是Java 5引入的特性,它们允许基本类型和对应的包装类之间的无缝转换。这种转换在编译时自动进行,使得代码更加简洁和易于编写。
### 自动装箱(Autoboxing)
自动装箱是将基本类型(如 `int`, `double` 等)自动转换为对应的包装类(如 `Integer`, `Double` 等)的过程。这个过程发生在将基本类型赋值给包装类对象或者将基本类型作为参数传递给需要包装类对象的方法时。
**示例:**
java
Integer refInt = 5; // 自动装箱
在上面的示例中,整数值 `5` 被自动转换为 `Integer` 类型的对象,然后赋值给 `refInt` 变量。
### 自动拆箱(Unboxing)
自动拆箱是将包装类的对象转换为对应的基本类型的过程。这通常发生在将包装类对象赋值给基本类型变量或者将包装类对象作为参数传递给需要基本类型的参数的方法时。
**示例:**
javaInteger intObj = new Integer(5);
int primitiveInt = intObj; // 自动拆箱
在上面的示例中,`Integer` 类型的对象 `intObj` 被自动转换为基本类型 `int`,然后赋值给 `primitiveInt` 变量。
### 缓存机制
对于 `Integer` 和 `Long` 类型,JVM 会缓存一定范围内的值(`Integer` 缓存 `-128` 到 `127`,`Long` 缓存 `-128` 到 `127`)。这意味着在这个范围内的自动装箱操作会返回相同的对象引用,这有助于减少内存使用并提高性能。
### 注意事项
- 自动装箱和拆箱虽然方便,但过度使用可能会导致性能问题,尤其是在循环内部进行大量的装箱和拆箱操作时。
- 当使用 `Integer` 等包装类时,要注意 `null` 值的可能性,因为包装类可以为 `null`,而基本类型不能。
- 在比较包装类对象时,应该使用 `equals()` 方法而不是 `==` 操作符,因为 `==` 比较的是对象引用,而 `equals()` 比较的是对象的值。
### 示例代码:
javapublic class AutoboxingUnboxingExample {
public static void main(String[] args) {
// 自动装箱
Integer num1 = 100;
// 自动拆箱
int num2 = num1;
// 使用equals()方法比较包装类对象的值
boolean areEqual = (num1.equals(100)); // true
// 使用==操作符比较包装类对象的引用
boolean areSameReference = (num1 == Integer.valueOf(100)); // true,因为-128到127之间的Integer对象会被缓存
System.out.println("num1 autoboxed from int to Integer: " + num1);
System.out.println("num2 unboxed from Integer to int: " + num2);
System.out.println("Are num1 and 100 equal? " + areEqual);
System.out.println("Are num1 and Integer.valueOf(100) the same reference? " + areSameReference);
}
}
在上面的示例中,演示了自动装箱、自动拆箱以及如何正确比较包装类对象。## 包装类特点
![image-20240805165331985](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165331985.png)
- -
## 基本数据类型与包装
- 基本类型与包装类:
- `boolean` 和 `Boolean`
- `byte` 和 `Byte`
- `short` 和 `Short`
- `int` 和 `Integer`
- `long` 和 `Long`
- `float` 和 `Float`
- `double` 和 `Double`
## 包装类共同点
![image-20240805165440427](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165440427.png)
## 自动装箱,拆箱
![image-20240805165544620](C:\Users\kepler\AppData\Roaming\Typora\typora-user-images\image-20240805165544620.png)
在Java中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是Java 5引入的特性,它们允许基本类型和对应的包装类之间的无缝转换。这种转换在编译时自动进行,使得代码更加简洁和易于编写。
### 自动装箱(Autoboxing)
自动装箱是将基本类型(如 `int`, `double` 等)自动转换为对应的包装类(如 `Integer`, `Double` 等)的过程。这个过程发生在将基本类型赋值给包装类对象或者将基本类型作为参数传递给需要包装类对象的方法时。
**示例:**
java
Integer refInt = 5; // 自动装箱
在上面的示例中,整数值 `5` 被自动转换为 `Integer` 类型的对象,然后赋值给 `refInt` 变量。
### 自动拆箱(Unboxing)
自动拆箱是将包装类的对象转换为对应的基本类型的过程。这通常发生在将包装类对象赋值给基本类型变量或者将包装类对象作为参数传递给需要基本类型的参数的方法时。
**示例:**
javaInteger intObj = new Integer(5);
int primitiveInt = intObj; // 自动拆箱
在上面的示例中,`Integer` 类型的对象 `intObj` 被自动转换为基本类型 `int`,然后赋值给 `primitiveInt` 变量。
### 缓存机制
对于 `Integer` 和 `Long` 类型,JVM 会缓存一定范围内的值(`Integer` 缓存 `-128` 到 `127`,`Long` 缓存 `-128` 到 `127`)。这意味着在这个范围内的自动装箱操作会返回相同的对象引用,这有助于减少内存使用并提高性能。
### 注意事项
- 自动装箱和拆箱虽然方便,但过度使用可能会导致性能问题,尤其是在循环内部进行大量的装箱和拆箱操作时。
- 当使用 `Integer` 等包装类时,要注意 `null` 值的可能性,因为包装类可以为 `null`,而基本类型不能。
- 在比较包装类对象时,应该使用 `equals()` 方法而不是 `==` 操作符,因为 `==` 比较的是对象引用,而 `equals()` 比较的是对象的值。
### 示例代码:
javapublic class AutoboxingUnboxingExample {
public static void main(String[] args) {
// 自动装箱
Integer num1 = 100;
// 自动拆箱
int num2 = num1;
// 使用equals()方法比较包装类对象的值
boolean areEqual = (num1.equals(100)); // true
// 使用==操作符比较包装类对象的引用
boolean areSameReference = (num1 == Integer.valueOf(100)); // true,因为-128到127之间的Integer对象会被缓存
System.out.println("num1 autoboxed from int to Integer: " + num1);
System.out.println("num2 unboxed from Integer to int: " + num2);
System.out.println("Are num1 and 100 equal? " + areEqual);
System.out.println("Are num1 and Integer.valueOf(100) the same reference? " + areSameReference);
}
}
在上面的示例中,演示了自动装箱、自动拆箱以及如何正确比较包装类对象。