第五章 ---- Java API
5.1 字符串类
字符串:就是指一连串的字符,它是由许多单个字符连接而成的。
如多个英文字母所组成的一个英文单词。字符串中可以包含任意字符,这些字符必须包含在一对双引号“”之内,例如“abc”。【(单个字符需要用单引号 ' ' ,例如字符 'a' )】
Java中定义了三个封装字符串的类,分别是String、StringBuffer和StringBuilder,它们位于java.lang包中,并提供了一系列操作字符串的方法,这些方法不需要导包就可以直接使用。
5.1.1 String类的初始化
使用字符串常量直接初始化一个String对象,具体代码如下:
String str1 = "abc"; //“abc”表示一个字符串常量
使用String类的构造方法初始化字符串对象,String类的常见构造方法如下表:
方法声明 |
功能描述 |
String() |
创建一个内容为空的字符串 |
String(String value) |
根据指定的字符串内容创建对象 |
String(char[] value) |
根据指定的字符数组创建对象 |
String(byte[] bytes) |
根据指定的字节数组创建对象 |
例如:
5.1.2 String类的常见操作
String类常用方法如下表:
方法声明 | 功能描述 |
int indexOf(int ch) | 返回指定字符ch在字符串中第一次出现位置的索引 |
int lastIndexOf(int ch) | 返回指定字符ch在字符串中最后一次出现位置的索引 |
int indexOf(String str) | 返回指定子字符串str在字符串第一次出现位置的索引 |
int lastIndexOf(String str) | 返回指定子字符串str在此字符串中最后一次出现位置的索引 |
char charAt(int index) | 返回字符串中index位置上的字符,其中index的取值范围是0~(字符串长度-1) |
Boolean endsWith(String suffix) | 判断此字符串是否以指定的字符串结尾 |
int length() | 返回此字符串的长度 |
boolean equals(Object anObject) | 将此字符串与指定的字符串比较 |
boolean isEmpty() | 判断字符串长度是否为0,如果为0则返回true,反之则返回flase |
boolean startsWith(String prefix) | 判断此字符串是否以指定的字符串开始 |
boolean contains(CharSequence cs) | 判断此字符串中是否包含指定的字符序列 |
String toLowerCase() | 使用默认语言环境的规则将String中的所有字符都转换为小写 |
String toUpperCase() | 使用默认语言环境的规则将String中的所有字符都转换为大写 |
static String valueOf(int i) | 将int变量i转换成字符串 |
char[] toCharArray() | 将此字符串转换为一个字符数组 |
String replace(CharSequence oldstr, CharSequence newstr) | 返回一个新的字符串,它是通过用 newstr替换此字符串中出现的所有 oldstr得到的 |
String[] split(String regex) | 根据参数regex将原来的字符串分割为若干个子字符串 |
String substring(int beginIndex) | 返回一个新字符串,它包含从指定的beginIndex处开始,直到此字符串末尾的所有字符 |
String substring(int beginIndex, int endIndex) | 返回一个新字符串,它包含从指定的beginIndex处开始,直到索引endIndex-1处的所有字符 |
String trim() | 返回一个新字符串,它去除了原字符串首尾的空格 |
1.字符串的获取功能
例如 : 获得字符串长度、获得指定位置的字符等
2.字符串的转换操作
例如 : 将字符串转换成数组的形式,将字符串中的字符进行大小写转换等。
/第7行代码使用String类的 toCharArray() 方法将一个字符串转为一个字符数组
//第17行代码使用静态方法 valueOf() 将一个int类型的整数转为字符串,第18行代码使用toUpperCase()方法将字符串中的字符都转为大写
/第20行代码使用 toLowerCase() 方法将字符串中的字符都转换为小写
其中 valueOf() 方法有多种重载的形式,float、double、char等其他基本类型的数据都可以通过valueOf()方法转为String字符串类型。
3.字符串的替换和去除空格操作
使用String类的replace()和trim()方法,进行字符串的替换和去除空格操作。
第5行代码定义了名称为s的字符串
第7行代码使用 replace()方法 将字符串s的“it”替换为“cn.it”
///第9行代码中定义了名称为s1的字符串,并在第10行代码使用 trim() 去除字符串两端的空格
trim()方法只能去除两端的空格,不能去除中间的空格。若想去除字符串中间的空格,需要调用String类的replace()方法。
///第11行代码使用 replace() 方法将字符串s1的“ ”(空格字符)替换为“”,这样做是为了去除字符串中所有的空格。
4.字符串的判断操作
例如 : 判断字符串是否以指定的字符串开始、结束,是否包含指定的字符串,字符串是否为空等。
在程序中可以通过 “==” 和 equals() 两种方式对字符串进行比较,但这两种方式有明显的区别:
equals()方法用于比较两个字符串中的字符内容是否相等
“==”方法用于比较两个字符串对象的地址是否相同
也就是说,对于两个内容完全一样的字符串对象,使用 equals 判断的结果是true,使用 == 判断的结果是false
String str1 = new String("abc");
String str2 = new String("abc");
// 结果为false,因为str1和str2是两个对象
System.out.println(str1 == str2);
// 结果为true,因为str1和str2字符内容相同
System.out.println(str1.equals(str2));
5.字符串的截取和分割
在String类中,
substring()方法用于截取字符串的一部分。
split()方法用于将字符串按照某个字符进行分割。
0 1 2 3 4 5 6 7 8 9
石家庄—武汉 —哈尔滨
第5行代码定义了名称为str的字符串
第7行代码在 substring()方法 中传入参数4,表示截取字符串中第5个之后的所有字符
/第8行代码在 substring()方法 中传入参数4和6,表示从第5个字符截取到第6个字符
为什么“汉”在数组中的索引是 5 ,而此处要写 6 ??
此处类似于“前闭后开”区间 【4,6),所以实际上取到的是索引为5和6的内容
/第10~19行代码先使用 split()方法 将字符串以 “-”进行分割,并将分割后的字符串数组命名为strArray,最后在for循环中使用if条件语句判断元素是否为最后一个元素,若不是最后一个元素则在该元素末尾添加“,”
字符串角标越界异常
String字符串在获取某个字符时,会用到字符的索引,当访问字符串中的字符时,如果字符的索引不存在,则会发生StringIndexOutOfBoundsException(字符串角标越界异常)。
5.1.3 StringBuffer类
String类的内存分配:
由于字符串是常量,因此一旦创建,其内容和长度是不可改变的。如果需要对一个字符串进行修改,则只能创建新的字符串。为了对字符串进行修改,Java提供了一个StringBuffer类(也称字符串缓冲区)
StringBuffer类和String类最大的区别在于它的内容和长度都是可以改变的。
StringBuffer类似一个字符容器,当在其中添加或删除字符时,并不会产生新的StringBuffer对象。
方法声明 | 功能描述 |
StringBuffer append(char c) | 添加参数到StringBuffer对象中 |
StringBuffer insert(int offset,String str) | 将字符串中的offset位置插入字符串str |
StringBuffer deleteCharAt(int index) | 移除此序列指定位置的字符 |
StringBuffer delete(int start,int end) | 删除StringBuffer对象中指定范围的字符或字符串序列 |
StringBuffer replace(int start,int end,String s) | 在StringBuffer对象中替换指定的字符或字符串序列 |
void setCharAt(int index, char ch) | 修改指定位置index处的字符序列 |
String toString() | 返回StringBuffer缓冲区中的字符串 |
StringBuffer reverse() | 将此字符序列用其反转形式取代 |
public class Example08 {public static void main(String[] args) {System.out.println("1、添加------------------------");add();System.out.println("2、删除------------------------");remove();System.out.println("3、修改------------------------");alter();}public static void add() {StringBuffer sb = new StringBuffer(); // 定义一个字符串缓冲区sb.append("abcdefg"); // 在末尾添加字符串System.out.println("append添加结果:" + sb);sb.insert(2, "123"); // 在指定位置插入字符串System.out.println("insert添加结果:" + sb);}public static void remove() {StringBuffer sb = new StringBuffer("abcdefg");sb.delete(1, 5); // 指定范围删除System.out.println("删除指定位置结果:" + sb);sb.deleteCharAt(2); // 指定位置删除System.out.println("删除指定位置结果:" + sb);sb.delete(0, sb.length()); // 清空缓冲区System.out.println("清空缓冲区结果:" + sb);}public static void alter() {StringBuffer sb = new StringBuffer("abcdef");sb.setCharAt(1, 'p'); // 修改指定位置字符System.out.println("修改指定位置字符结果:" + sb);sb.replace(1, 3, "qq"); // 替换指定位置字符串或字符System.out.println("替换指定位置字符(串)结果:" + sb);System.out.println("字符串翻转结果:" + sb.reverse());}}
//第12~18行代码创建了add()方法,用于演示StringBuffer的添加操作,在第13行代码中创建了一个StringBuffer类型的字符串sb,第14行代码使用append()方法在字符串sb的末尾添加了新的字符串,第16行代码使用insert()方法在字符串sb索引为2的位置插入字符串“123”。
使用append()方法插入的新字符串始终位于字符串sb的末尾,而insert()方法则可以将新字符串插入指定位置。
///第19~27行代码创建了remove()方法,用于演示StringBuffer的字符串删除操作,在第18行代码中创建了一个StringBuffer类型的字符串sb,在第21行代码使用delete()方法删除字符串下标从1到5的字符,第23行代码使用deleteCharAt()方法删除字符串下标2之后的所有字符,第25行的delete()方法用于清空缓冲区结果。
第28~35行代码创建了alter()方法,用于演示StringBuffer的字符串替换和反转的操作,在第29行代码中创建了一个StringBuffer类型的字符串sb,在第30行代码中使用setCharAt()方法修改下标为1的字符为“p”,第30行代码中使用replace()方法替换下标从1到3的字符为“qq”,第35行代码中使用reverse()方法将字符串反转。
5.1.4 StringBuilder类
StringBuilder类也可以对字符串进行修改
StringBuffer类和StringBuilder类的对象都可以被多次修改,并不产生新的未使用对象
StringBuilder它与StringBuffer之间最大不同在于StringBuilder的方法是线程安全的,也就是说StringBuffer不能被同步访问,而StringBuilder可以。
对比String、StringBuilder和StringBuffer的运行效率:
public class Example09 {private static final int TIMES = 100000;public static void main(String[] args) {Example09.testString();Example09.testStringBuffer();Example09.testStringBuilder();}//String时间效率测试public static void testString() {long startTime = System.currentTimeMillis();String str = "";for (int i = 0; i < TIMES; i++) {str += "test";}long endTime = System.currentTimeMillis();System.out.println("String test usedtime: " + (endTime - startTime));}//StringBuffer时间效率测试(线程安全)public static void testStringBuffer() {long startTime = System.currentTimeMillis();StringBuffer str = new StringBuffer();for (int i = 0; i < TIMES; i++) {str.append("test");}long endTime = System.currentTimeMillis();System.out.println("StringBuffer test usedtime: " + (endTime - startTime));}//StringBuffer时间效率测试(非线程安全)public static void testStringBuilder() {long startTime = System.currentTimeMillis();StringBuilder str = new StringBuilder();for (int i = 0; i < TIMES; i++) {str.append("test");}long endTime = System.currentTimeMillis();System.out.println("StringBuilder test usedtime: " + (endTime - startTime));}
三者的工作效率为StringBuilder>StringBuffer>String
不同:
String类表示的字符串是常量,一旦创建后,内容和长度都是无法改变的。
StringBuffe和StringBuilder表示字符容器,其内容和长度可以随时修改。
在操作字符串时,如果该字符串仅用于表示数据类型,则使用String类即可,但是如果需要对字符串中的字符进行增删操作,则使用StringBuffer与StringBuilder类。
如果有大量字符串拼接操作,不要求线程安全的情况下,采用StringBuilder更高效。相反如果需要线程安全则需要使用StringBuffer。
equals()方法对于StringBuffer类与StringBuilder类来言并不起作用
String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.equals(s2)); // 打印结果为true StringBuffer sb1 = new StringBuffer("abc"); StringBuffer sb2 = new StringBuffer("abc"); System.out.println(sb1.equals(sb2)); // 打印结果为false StringBuilder sbr1=new StringBuilder("abc"); StringBuilder sbr2=new StringBuilder("abc"); System.out.println(sbr1.equals(sbr2));
String类对象可以用操作符“+”进行连接,而StringBuffer类对象之间不能。
String s1 = "a"; String s2 = "b"; String s3 = s1+s2; // 合法 System.out.println(s3); // 打印输出 ab StringBuffer sb1 = new StringBuffer("a"); StringBuffer sb2 = new StringBuffer("b"); StringBuffer sb3 = sb1 + sb2; // 编译出错
5.2.1 System类
System类定义了一些与系统相关的属性和方法,它所提供的属性和方法都是静态的,因此,想要引用这些属性和方法,直接使用System类调用即可。
方法名称 | 功能描述 |
static void exit(int status) | 该方法用于终止当前正在运行的Java虚拟机,其中参数status表示状态码,若状态码非0 ,则表示异常终止 |
static void gc() | 运行垃圾回收器,并对垃圾进行回收 |
static void currentTimeMillis() | 返回以毫秒为单位的当前时间 |
static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length) | 从src引用的指定源数组复制到dest引用的数组,复制从指定的位置开始,到目标数组的指定位置结束 |
static Properties getProperties() | 取得当前的系统属性 |
static String getProperty(String key) | 获取指定键描述的系统属性 |
1.arraycopy()方法
arraycopy()方法用于将数组从源数组复制到目标数组,声明格式如下:
static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
● src:表示源数组。 ● dest:表示目标数组。 ● srcPos:表示源数组中拷贝元素的起始位置。 ● destPos:表示拷贝到目标数组的起始位置。 ● length:表示拷贝元素的个数。
/第5~6行代码创建了两个数组fromArray和toArray,分别代表源数组和目标数组
///第7行代码中当调用arraycopy()方法进行元素拷贝时,由于指定了从源数组中索引为2的元素开始拷贝,并且拷贝4个元素存放在目标数组中索引为3的位置,因此,在打印目标数组的元素时,程序首先打印的是数组toArray的前三个元素20、21、22,然后打印的是从fromArray中拷贝的四个元素12、13、14、15
2.currentTimeMillis()方法
currentTimeMillis()方法用于获取当前系统的时间,返回值是long类型的值,该值表示当前时间与1970年1月1日0点0分0秒之间的时间差,单位是毫秒,通常也将该值称作时间戳。
通过一个for循环的求和的案例计算程序运行时所消耗的时间:
///第6~9行代码演示了数字的求和操作,程序在求和开始和结束时,分别调用了currentTimeMillis()方法获得了两个时间戳(系统当前时间),两个时间戳之间的差值便是求和操作所耗费的时间
3.getProperties()和getProperty()方法
System类的getProperties()方法用于获取当前系统的全部属性,该方法会返回一个Properties对象,其中封装了系统的所有属性,这些属性是以键值对形式存在的。getProperty() 方法用于根据系统的属性名获取对应的属性值。
//第6行代码通过System的getProperties()方法获取了系统的所有属性
/第8行代码通过Properties的propertyNames()方法获取所有的系统属性的key,并使用名称为propertyNames的Enumeration对象接受获取到的key值
/第9~15行代码对Enumeration对象进行迭代循环,通过Enumeration的nextElement()方法获取系统属性的key,再通过System的getProperty(key)方法获取当前key对应的value,最后将所有系统属性的键以及对应的值打印出来。从运行结果中可以看出,这些系统属性包括虚拟机版本号,用户的国家、操作系统的版本等。
4.gc()方法
在Java中,当一个对象成为垃圾后仍会占用内存空间,时间一长,就会导致内存空间的不足。针对这种情况,Java中引入了垃圾回收机制。有了这种机制,程序员不需要过多关心垃圾对象回收的问题,Java虚拟机会自动回收垃圾对象所占用的内存空间。
除了等待Java虚拟机进行自动垃圾回收外,还可以通过调用System.gc()方法通知Java虚拟机立即进行垃圾回收。当一个对象在内存中被释放时,它的finalize()方法会被自动调用,因此可以在类中通过定义finalize()方法观察对象何时被释放。
第5~7行代码定义了一个finalize()方法,该方法的返回值必须为void
第12~13行代码创建了两个对象p1和p2,然后将两个对象设置为null,这意味着新创建的两个对象成为垃圾了
///第18行代码通过“System.gc()”语句通知虚拟机进行垃圾回收。需要注意的是,Java虚拟机的垃圾回收操作是在后台完成的,程序结束后,垃圾回收的操作也将终止
第程序的第19~21行代码使用了一个for循环,延长程序运行的时间,从而能够更好地看到垃圾对象被回收的过程。
从运行结果可以看出,虚拟机针对两个垃圾对象进行了回收,并在回收之前分别调用两个对象的finalize()方法。 除了以上案例涉及到的方法,System类还有一个常见的方法exit(int status),该方法用于终止当前正在运行的Java虚拟机,其中参数status用于表示当前发生的异常状态,通常指定为0,表示正常退出,否则表示异常终止。
5.2.2 Runtime类
Runtime类用于表示虚拟机运行时的状态,它用于封装JVM虚拟机进程。每次使用java命令启动虚拟机都对应一个Runtime实例,并且只有一个实例,因此在Runtime类定义的时候,它的构造方法已经被私有化了(单例设计模式的应用),对象不可以直接实例化。若想在程序中获得一个Runtime实例,只能通过以下方式:
Runtime run = Runtime.getRuntime();
由于Runtime类封装了虚拟机进程,因此,在程序中通常会通过该类的实例对象来获取当前虚拟机的相关信息
方法声明 |
功能描述 |
getRuntime() | 该方法用于返回当前应用程序的运行环境对象。 |
exec(String command) | 该方法用于根据指定的路径执行对应的可执行文件 |
freeMemory() | 该方法用于返回Java虚拟机中的空闲内存量,以字节为单位。 |
maxMemory() | 该方法用于返回Java虚拟机的最大可用内存量。 |
availableProcessors() | 该方法用于返回当前虚拟机的处理器个数 |
totalMemory() | 该方法用于返回Java虚拟机中的内存总量 |
1.获取当前虚拟机信息
Runtime类可以获取当前Java虚拟机的处理器的个数、空闲内存量、最大可用内存量和内存总量的信息。
public class Example14 {public static void main(String[] args) {Runtime rt = Runtime.getRuntime(); // 获取System.out.println("处理器的个数: " + rt.availableProcessors()+"个");System.out.println("空闲内存数量: " + rt.freeMemory() / 1024 / 1024 + "M");System.out.println("最大可用内存数量: " + rt.maxMemory() / 1024 / 1024 + "M");System.out.println("虚拟机中内存总量: " + rt.totalMemory() / 1024 / 1024 + "M");}}
///第3行代码中通过Runtime的getRuntime()方法创建一个名称为rt的Runtime实例对象
/第4~5行代码通过Runtime的availableProcessors()方法获取了Java虚拟机的处理器个数
/第6~7行代码通过Runtime的freeMemory()方法获取了Java虚拟机的空闲内存数
第8~9行代码通过Runtime的maxMemory()方法获取了Java虚拟机的最大可用内存数量
///第10~11行代码通过Runtime的totalMemory()方法获取了Java虚拟机中内存总量
由于每个人的机器配置不同,该文件的打印结果可能不同,另外空闲内存数、可用最大内存数和内存总量都是以字节为单位计算的,上述运行结果已经将字节换算成了兆(M)。
2.操作系统进程
Runtime类中提供了一个exec()方法,该方法用于执行一个dos命令,从而实现和在命令行窗口中输入dos命令同样的效果。例如,通过运行“notepad.exe”命令打开一个Windows自带的记事本程序。
import java.io.IOException;public class Example15{public static void main(String[] args) throws IOException {Runtime rt = Runtime.getRuntime(); // 创建Runtime实例对象rt.exec("notepad.exe"); // 调用exec()方法}}
/第4行代码中通过Runtime的getRuntime()方法创建一个名称为rt的Runtime实例对象
/在第5行代码中调用Runtime的exec()方法,并将 “otepad.exe”作为参数传递给exec()方法。运行程序会在桌面上打开一个记事本。
程序运行后,会在Windows系统中产生一个新的进程notepad.exe,可以通过任务管理器进行观察
Runtime类的exec()方法返回一个Process对象,该对象就是exec()所生成的新进程,通过该对象可以对产生的新进程进行管理,如关闭此进程只需调用destroy()方法即可。具有代码如下所示:
public class Example {public static void main(String[] args) throws Exception {Runtime rt = Runtime.getRuntime(); // 创建一个Runtime实例对象Process process = rt.exec("notepad.exe");//得到表示进程的Process对象Thread.sleep(3000); // 程序休眠3秒process.destroy(); // 杀掉进程} }
///上述代码中,通过调用Process对象的destroy()方法关闭了打开的记事本。为了突出演示的效果,使用了Thread类的静态方法sleep(long millis)使程序休眠了3秒,因此,程序运行后,会看到打开的记事本在3秒后自动关闭了。
5.3.1 Math类
Math类提供了大量的静态方法来便于我们实现数学计算,如求绝对值、取最大或最小值等。
方法声明 |
功能描述 |
abs() |
该方法用于计算绝对值 |
sqrt() |
该方法用于计算方根 |
ceil() |
该方法用于计算大于参数的最小整数 |
floor() |
该方法用于计算小于参数的最小整数 |
round() |
该方法用于计算小数进行四舍五入后的结果 |
max() |
该方法用于计算两个数的较大值 |
min() |
该方法用于计算两个数的较小值 |
random() |
该方法用于生成一个大于0.0小于1.0的随机值 |
sqrt() |
该方法用于计算开平方的结果 |
pow() |
该方法用于计算指数函数的值 |
5.3.2 Random类
Java的java.util包中有一个Random类,它可以在指定的取值范围内随机产生数字。Random类中提供了两个构造方法如下表。
方法声明 |
功能描述 |
Random() |
构造方法,用于创建一个伪随机数生成器 |
Random(long seed) |
构造方法,使用一个long型的seed种子创建伪随机数生成器 |
Random类的两个构造方法。
其中第一个构造方法是无参的,通过它创建的Random实例对象每次使用的种子是随机的,因此每个对象所产生的随机数不同。
如果希望创建的多个Random实例对象产生相同的随机数,则可以在创建对象时调用第二个构造方法,传入相同的参数即可。
第一种方法 无参构造:
第二种方法 有参构造:
相对于Math的random()方法而言,Random类提供了更多的方法来生成各种伪随机数,不仅可以生成整数类型的随机数,还可以生成浮点类型的随机数。Random类常用的方法如下表。
方法声明
功能描述
double nextDouble()
随机生成double类型的随机数
float nextFloat()
随机生成float类型的随机数
int nextInt()
随机生成int类型的随机数
int nextInt(int n)
随机生成0~n之间int类型的随机数
Random类的nextDouble()方法返回的是0.0和1.0之间double类型的值,nextFloat()方法返回的是0.0和1.0之间float类型的值,nextInt(int n)返回的是0(包括)和指定值n(不包括)之间的值。
5.4 日期时间类
在日期时间类中了包含LocalDate类、LocalTime类、Instant类、Duration类以及Period类等,这些类都包含在java.time包中
类的名称 |
功能描述 |
Instant |
表示时刻,代表的是时间戳 |
LocalDate |
不包含具体时间的日期 |
LocalTime |
不含日期的时间 |
LocalDateTime |
包含了日期及时间 |
Duration |
基于时间的值测量时间量 |
Period |
计算日期时间差异,只能精确到年月日 |
Clock |
时钟系统,用于查找当前时刻 |
5.4.1 Instant类
Instant 类代表的是某个时间。其内部是由两个Long字段组成,第一部分保存的是标准Java计算时代(就是1970年1月1日开始)到现在的秒数,第二部分保存的是纳秒数。
方法声明 |
功能描述 |
now() |
从系统时钟获取当前瞬时 |
now(Clock clock) |
从指定时钟获取当前瞬时 |
ofEpochSecond(long epochSecond): |
使用从自标准Java计算时代开始的秒数获得一个Instant的实例。 |
ofEpochMilli(long epochMilli): |
使用从自标准Java计算时代开始的秒数获得一个Instant的实例。 |
getEpochSecond(): |
从1970-01-01T00:00:00Z的Java时代获取秒数。 |
getNano(): |
从第二个开始就从时间线获得纳秒的数量。 |
parse(CharSequence text) |
从一个文本字符串(如2007-12-03T10:15:30.00Z获取一个Instant的实例。 |
from(TemporalAccessor tenporal) |
从时间对象获取一个Instant的实例。 |
///第8行代码使用Instant的now()方法获取了系统中的当前时刻
///第10行代码使用Instant的ofEpochMilli()方法获取了计算机元年增加毫秒数后的结果
///第12行代码使用Instant的ofEpochSecond()方法获取了计算机元年增加秒数后的结果
///第14~15行代码使用Instant的getEpochSecond()方法获取了从“007-12-03T10:15:30.44Z”到现在的秒值
//第16~17行代码使用getNano()方法获取了从“007-12-03T10:15:30.44Z”到现在的纳秒值
//第18~19行代码使用from()方法从时间对象获取了Instant的实例。从运行结果中可以看出每个方法所输出结果的格式。需要注意的是,now()方法默认获取的是西六区时间;parse()是从文本字符串获取的Instant实例
5.4.2 LocalDate类
LocalDate类仅用来表示日期。通常表示的是年份和月份,该类不能代表时间线上的即时信息,只是日期的描述。在LocalDate类中提供了两个获取日期对象的方法 now() 和 of(int year, int month, int dayOfMonth) , 具体代码如下所示:
//从一年,一个月和一天获得一个 LocalDate的实例
//of(int year, int month, int dayOfMonth) LocalDate date = LocalDate.of(2020, 12, 12);//从默认时区的系统时钟获取当前日期
LocalDate now1 = LocalDate.now();
方法声明 |
功能描述 |
getYear() |
获取年份字段 |
getMonth() |
使用Month枚举获取月份字段 |
getMonthValue() |
将月份字段从1到12 |
getDayOfMonth() |
获取当月第几天字段 |
format(DateTimeFormatter formatter) |
使用指定的格式化程序格式化此日期。 |
isBefore(ChronoLocalDate other) |
检查此日期是否在指定日期之前。 |
isAfter(ChronoLocalDate other) |
检查此日期是否在指定日期之后。 |
isEqual(ChronoLocalDate other) |
检查此日期是否等于指定的日期。 |
isLeapYear() |
根据ISO培训日历系统规则,检查年份是否是闰年。 |
parse(CharSequence text) |
从一个文本字获取一个 LocalDate的实例。 |
parse(CharSequence text, DateTimeFormatter formatter) |
使用特定格式化 LocalDate从文本字符串获取 LocalDate的实例。 |
plusYears(long yearsToAdd) |
增加指定年份 |
plusMonths(long monthsToAdd) |
增加指定月份 |
plusDays(long daysToAdd) |
增加指定日数 |
minusYears(long yearsToSubtract) |
减少指定年份 |
minusMonths(long monthsToSubtract) |
减少指定月份 |
minusDays(long daysToSubtract) |
减少指定日数 |
withYear(int year) |
指定年 |
withMonth(int month) |
指定月 |
withDayOfYear(int dayOfYear) |
指定日 |
/第9行代码定义了一个名称为now的LocalDate无参实例
第10行代码定义了一个名称为of的LocalDate有参实例,参数值为“2015,12,12”
第12~15行代码使用了LocalDate的获取及格式化的相关方法,其中第12行代码使用LocalDate的getYerar()方法获取了当前的年份
///第13行代码使用LocalDate的getMonthValue()方法获取了当前的月份
///第14行代码使用LocalDate的getDayOfMonth()方法获取了当前在本月的第几天
///第15行代码使用LocalDate的farmot()方法将日期格式设置为(yyyy年MM月dd日)
///第17~20行代码使用了LocalDate判断的相关方法,其中第17行代码使用LocalDate的isBefore()判断日期of是否在当前时间前,第18行代码使用LocalDate的isAfter()方法判断日期of是否在当前时间后,第19行代码使用LocalDate的equals()方法判断日期of是否和now相等,第20行代码使用LocalDate的isLeapYear()方法判断日期of是否为闰年
第23~27行代码使用了LocalDate解析以及加减操作的相关方法,其中第23行代码定义了一个名称为dateStr的字符串,dateStr的值为“2020—02—01”
///第24行代码使用LocalDate的parse()方法将dateStr解析为日期对象
///第25行代码使用LocalDate的plusYears()方法将now实例年份加1
///第26行代码使用LocalDate的minusDays()方法将now实例天数减10
第27行代码使用LocalDate的withYear()方法将now实例年份指定为2014
5.4.3 LocalTime类与LocalDataTime类
LocalTime类用来表示时间,通常表示的是小时分钟秒
与LocalDate类一样,该类不能代表时间线上的即时信息,只是时间的描述
在LocalTime类中提供了获取时间对象的方法,与LocalData用法类似。 同时LocalTime类也提供了与日期类相对应的时间格式化、增减时分秒等常用方法,这些方法与日期类相对应。
LocalDataTime类是LocalDate类与LocalTime类的综合,它即包含日期也包含时间,通过查看API可以知道,LocalDataTime类中的方法包含了LocalDate类与LocalTime类的方法。
需要注意的是,LocalDateTime默认的格式是 2020-02-29T21:23:26.774,这可能与我们经常使用的格式不太符合,所以它经常和DateTimeFormatter一起使用指定格式,除了LocalData与LocalTime类中的方法,额外提供了转换的方法
下面示例 LocalDataTime类中特有的方法 :
第9行代码定义了一个名称为now的LocalDateTime实例
在10行代码直接打印当前日期now
第11行代码使用LocalDateTime的toLocalDate()方法将now转换为相应的LocalDate实例
第12行代码使用toLocalTime()方法将now转换为相应的LocalTime实例
第14行代码使用DateTimeFormatter的ofPattern()方法将时间格式指定为“yyyy年MM月DD日 HH时mm分ss秒”
///第15行代码使用LocalDateTime的format()方法将now的时间按指定格式打印
5.4.4 Period和Duration类
Duration类基于时间值,其作用范围是天、时、分、秒、毫秒和纳秒
Duration类的常用方法如下表:
方法声明 |
功能描述 |
between(Temporal startInclusive, Temporal endExclusive) |
获取一个Duration表示两个时间对象之间的持续时间。 |
toDays(): |
将时间转换为以天为单位的 |
toHours(): |
将时间转换为以时为单位的 |
toMinutes(): |
将时间转换为以分钟为单位的 |
toMillis(): |
将时间转换为以毫秒为单位的 |
toNanos(): |
将时间转换为以纳秒为单位的 |
///第10行代码通过between()方法计算出start与end的时间间隔
第12行代码通过toNanos()方法将这个时间间隔转化为纳秒为单位的
///第13行代码通过toMillis()方法将这个时间间隔转化为毫秒为单位的
///第14行代码通过toHours()方法将这个时间间隔转化为小时为单位的
2. Period类
Period主要用于计算两个日期的间隔,与Duration相同,也是通过between计算日期间隔,并提供了获取年月日的三个常用方法,分别是 getYears()、getMonths()和getDays()。
/第11行代码通过between()方法计算出birthday与now的时间间隔
//第12行代码通过getYears()方法获取时间间隔的年份
//第13行代码通过getMonths()方法获取时间间隔的月份
//第14行代码通过getDays()方法获取时间间隔的天数
需求:
二月是一个有趣的月份,平年的二月有28天,闰年的二月有29天。闰年每四年一次,在判断闰年时,可以使用年份除以4,如果能够整除,则该年是闰年。 本例要求编写一个程序,从键盘输入年份,根据输入的年份计算这一年的2月有多少天。在计算二月份天数时,可以使用日期时间类的相关方法实现
方式一: 四年一闰,百年不闰,四百年再闰
import java.util.Scanner;public class MonDay {public static void main(String[] args) {int day ;Scanner year = new Scanner(System.in); //接收年份System.out.println("请输入想要查询的年份 :");int Year = year.nextInt();Scanner month = new Scanner(System.in); //接收月份System.out.println("请输入想要查询的月份 :");int Month = month.nextInt();if (Month != 2) {if (Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12) {day = 31;} else {day = 30 ;}System.out.println(Year + "年的" + Month + "月,有" + day + "天。");}if (Month == 2 ){if(Year % 4 == 0 & Year % 100 != 0 || Year % 100 == 0 & Year % 400 == 0) {System.out.println(Year + "年是闰年," + Month + "月有29天。"); //闰年}else {System.out.println(Year + "年是平年," + Month + "月有28天。"); //平年}}} }
方式二: LocalDate isLeapYear()
import java.time.LocalDate; import java.util.Scanner;public class LocalDateTest01 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入年份:");int year = sc.nextInt();LocalDate of = LocalDate.of(year,1,1);boolean leapYear = of.isLeapYear();if (leapYear){System.out.println(29);}else{System.out.println(28);}} }
方式三:
mport java.time.LocalDate; import java.util.Scanner;public class LocalDateTest02 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入年份:");int year = sc.nextInt();//方式三LocalDate of = LocalDate.of(year,3,1);LocalDate localDate = of.minusDays(1);System.out.println(localDate);} }
5.5 包装类
Java是一种面向对象的语言,Java中的类可以把方法与数据连接在一起,但是Java语言中却不能把基本的数据类型作为对象来处理。为了解决这样的问题,JDK中提供了一系列的包装类,可以把基本数据类型的值包装为引用数据类型的对象,在Java中,每种基本类型都有对应的包装类。
基本数据类型 |
对应的包装类 |
byte |
Byte |
char |
Character |
int |
Integer |
short |
Short |
long |
Long |
float |
Float |
double |
Double |
boolean |
Boolean |
包装类和基本数据类型在进行转换时,引入了 装箱 和 拆箱 的概念,其中装箱是指将基本数据类型的值转为引用数据类型,反之,拆箱是指将引用数据类型的对象转为基本数据类型
//在创建Integer对象时,将int类型的变量a作为参数传入,从而转为Integer类型。
/在创建基本数据类型int时,将Integer类型的值in直接赋值给l,从而转为int类型。
Integer类除了具有Object类的所有方法外,还有一些特有的方法:
方法声明
功能描述
Integer valueOf(int i)
返回一个表示指定的int值的 Integer 实例
Integer valueOf(String s)
返回保存指定的String的值的 Integer 对象
int parseInt(String s)
将字符串参数作为有符号的十进制整数进行解析
intValue()
将 Integer 类型的值以int类型返回
上面表格列举了Integer的常用方法
其中的intValue()方法可以将Integer类型的值转为int类型,这个方法可以用来进行手动拆箱操作。
parseInt(String s)方法可以将一个字符串形式的数值转成int类型,valueOf(int i)可以返回指定的int值为Integer实例。
上述代码演示了手动拆箱的过程,Integer对象通过调用intValue()方法,将Integer对象转为int类型,从而可以与int类型的变量a进行加法运算,最终将运算结果正确打印。
/valueOf()方法将int类型的值转为Integer的实例。Integer对象通过调用包装类Integer的parseInt()方法将字符串转为整数,将字符串转为int类型,从而可以与int类型的常量10进行加法运算。
使用包装类时,需要注意以下几点:
(1)包装类都重写了Object类中的toString()方法,以字符串的形式返回被包装的基本数据类型的值。
(2)除了Character外,包装类都有valueOf(String s)方法,可以根据String类型的参数创建包装类对象,但参数字符串s不能为null,而且字符串必须是可以解析为相应基本类型的数据,否则虽然编译通过,但运行时会报错。具体示例如下:
Integer i = Integer.valueOf("123"); // 合法
Integer i = Integer.valueOf("12a"); // 不合法
(3)除了Character外,包装类都有parseXxx(String s)的静态方法,将字符串转换为对应的基本类型的数据。参数s不能为null,而且同样字符串必须可以解析为相应基本类型的数据,否则虽然编译通过,但运行时会报错。具体示例如下:
int i = Integer.parseInt("123"); // 合法 Integer in = Integer.parseInt("itcast"); // 不合法
5.6 正则表达式
正则表达式就是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。
5.6.1 元字符
正则表达式由普通字符(例如字符a-z)和特殊字符(元字符)组成的文字模式
元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
正则表达式常见的元字符如下表:
元字符 |
功能描述 |
\ |
转义字符,例如"\n"匹配"\n" |
^ |
正则表达式的开头标志 |
$ |
正则表达式的结尾标志 |
* |
匹配零次或多次 |
+ |
匹配一次或多次 |
? |
匹配一次或零次 |
. |
匹配任意字符 |
{n} |
匹配n次 |
{n,} |
至少匹配n次 |
{n,m} |
n<=m,最少匹配n次,最多匹配m次 |
x|y| |
匹配x或y |
[xyz] |
字符集合。匹配所包含的任意一个字符 |
[a-z] |
字符范围。匹配指定范围内的任意字符 |
[a-zA-Z] |
匹配a到z或Z |
[a-z] |
字符范围。匹配指定范围内的任意字符 |
\d |
数字:[0-9] |
\D |
非数字: [^0-9] |
\s |
空白字符:[ \t\n\x0B\f\r] |
\S |
非空白字符:[^\s] |
\w |
单词字符:[a-zA-Z_0-9] |
\b |
单词边界 |
\B |
非单词边界 |
\A |
输入的开头 |
\G |
上一个匹配的结尾 |
\Z |
输入的结尾,仅用于最后的结束符(如果有的话) |
\z |
输入的结尾 |
\b |
单词边界 |
5.6.2 Pattern类和Matcher类
1. Pattern类
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,
具体代码如下所示:
Pattern p=Pattern.compile("\\w+");
Pattern类常用方法如下表:
方法声明 |
功能描述 |
split(CharSequence input) |
将给定的输入序列分成这个模式的匹配 |
Matcher matcher (CharSequence input) |
创建一个匹配器,匹配给定的输入与此模式 |
Static boolean matches (String regex, CharSequence input) |
编译给定的正则表达式,并尝试匹配给定的输入 |
///上述代码中,第5行代码通过compile()方法创建一个正则表达式
/第6~7行代码通过split()方法将字符串按照给定的模式进行分割,并返回名称为str的数组,
///第8~11行代码通过matcher()方法判断是否匹配pattern的输入模式
第12~14行代码通过pattern()方法判断Matcher对象是由哪个Pattern对象创建的
第15~18行代码通过for循环输出str数组。需要注意的matches(Stringregex,CharSequence input)方法用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串。
2. Matcher类
Matcher类用于在给定的Pattern实例的模式控制下进行字符串的匹配工作,同理Matcher的构造方法也是私有的,不能直接创建,只能通过Pattern. matcher(CharSequence input)方法得到该类的实例。
Matcher类的常用方法如下表:
方法声明 |
功能描述 |
boolean matches() |
对整个字符串进行匹配,只有整个字符串都匹配了才返回true |
boolean lookingAt() |
对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true |
boolean find() |
对字符串进行匹配,匹配到的字符串可以在任何位置 |
int end() |
返回最后一个字符匹配后的偏移量 |
string group() |
返回匹配到的子字符串 |
int start() |
返回匹配到的子字符串在字符串中的索引位置 |
/第6~9行代码通过matches()方法判断字符串是否匹配
第10~12行代码通过lookingAt()方法对前面的字符串进行匹配
第13~20行代码通过find()方法对字符串进行匹配,匹配到的字符串可以在任何位置
第21行代码通过start()方法得出上一个字符匹配的起始索引
///第22行代码通过end()方法得出最后一个字符匹配后的偏移量
//第23行代码通过group()方法得出匹配到的字符串
5.6.3 String类对正则表达式的支持
String类提供了3个方法支持正则操作,如下表:
方法声明 |
功能描述 |
boolean matches(String regex) |
匹配字符串 |
String replaceAll(String regex, String replacement) |
字符串替换 |
String[] split(String regex) |
字符串拆分 |
/String类提供的方法可以很方便对字符串进行操作。需要注意的是:
String类matches(String regex)方法的使用同Pattern类和Matcher类中该方法使用一样,必须匹配所有的字符串才返回true,否则返回false
第五章 ---- Java API相关推荐
- 第五章 Java API(九)
5.6正则表达式 5.6.1元字符 正则表达式是由普通字符(如字符a -z)和特殊字符(元字符)组成的文字模式.元字符是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符 ...
- 第五章 Java API(四)
5.2 System类与Runtime类 5.2.1 System类 System类定义了一些与系统相关的属性和方法,它所提供的属性和方法都是静态的. System类的常用方法 方法名称 功能描述 s ...
- 第五章 Java 中的 wait、notify 和 notifyAll 方法示例
您可能已经注意到 Object 类具有三个 final 方法,分别称为 wait.notify 和 notifyAll.这些方法用于线程间通信.Java 5 引入了执行器框架,它为您处理线程间通信,并 ...
- 深入Java虚拟机读书笔记第五章Java虚拟机
Java虚拟机 Java虚拟机之所以被称之为是虚拟的,就是因为它仅仅是由一个规范来定义的抽象计算机.因此,要运行某个Java程序,首先需要一个符合该规范的具体实现. Java虚拟机的生命周期 一个运行 ...
- 第五章 Java的基础类之String、StringBuffer、StringBuilder(下)
前言 在现实世界中,既有独居动物,也有群居动物.人作为一种高等动物,是一种群居动物.群居动物都离不开家族,String类上篇中已经详细分析了它的源码实现,几乎涵盖了大部分的源码.作为一个优秀的类,它是 ...
- 第五章 Java中的String类和StringBuffer(上)
为什么不从第一章开始记录? 因为,博主最近在刷"蓝桥杯"的算法题,题目中遇到了许多和字符串相关的题目. 比如:要求程序对用户输入的串进行处理.具体规则如下: 1. 把每个单词的首 ...
- 第六章 Java API
一.填空题 1.在Java中定义了3个类来封装对字符串的操作,他们分别是String.StringBuffer和StringBuilder. 2.Java中用于获取String字符串长度的方法是len ...
- 第五章 Java字符串总结
5.1 String 类 5.1.1 声明字符串 字符串是常量,它们可以显示任何文字信息, ' ' 字符 一个 " " 字符串 多个 5.1.2 创建字符串 ...
- 【Java基础系列教程】第十五章 Java 正则表达式详解
一.正则表达式概述 什么是正则表达式 正则表达式:用于匹配规律规则的表达式,正则表达式最初是科学家对人类神经系统的工作原理的早期研究,现在在编程语言中有广泛的应用.正则表达式通常被用来检索.替换那些符 ...
最新文章
- 机智云官网用到的库-grid.css我解析
- excel公式 某一个单元格等于另一个单元格的值_EXCEL函数学习5——COUNTIF函数
- ERP系统开发平台 (C#语言,支持多数据库)
- Linux make menuconfig查找并快速跳转指定驱动选项
- 【转】为控制台窗口建立消息队列
- 2场直播丨CloudQuery最佳实践,
- C# Get请求携带body
- C# 读取json文件与写json文件
- Oracle 11g 创建数据库
- dota2地区服务器延迟,DOTA2 TI8预选赛:南美服务器爆炸比赛延迟
- VR全景制作教程|VR全景拍摄和制作竟如此简单
- Simulink代码生成: Switch模块及其代码
- Liunx最全最常用的命令-初学者专属
- 拳皇世界6月13服务器维护,拳皇世界闪退怎么办 对症下药马上好
- TCP Congestion性能测试分析
- 【TCP拥塞控制算法(TCP congestion control algorithm)学习笔记】
- 人工智能会代替人工翻译?知行翻译:这是不可能地!
- 学习计算机软件技术感想,信息技术学习心得体会
- android 蒲公英 类似平台,Jenkins之android APP打包上传蒲公英平台
- mybatis的原理详解