目录
一、String 类、StringBuffer 和 StringBuilder 类
四、Data 与 Calendar、DateFormat 类
Java 类库就是 Java API (应用程序接口),是系统提供的已实现的标准类的集合,使用 Java 类库可以完成涉及字符串处理、图形、网络等多方面的操作。
API(Application Programming Interface)就是应用程序编程接口。
假设现在需要编写一个机器人程序,去控制一个机器人踢足球,程序需要向机器人发出向前跑、向后转、射门、拦截等命令,没有编写程序的人很难想象如何编写这样的程序。但对于有编程经验的人来说,就知道机器人厂商一定会提供一些控制这些机器人的 Java类,该类有操作机器人的各种动作的方法,只需要为每个机器人安排一个该类的实例对象,再调用这个对象的各种方法,机器人就会去执行动作。这个 Java 类就是机器人厂商提供的应用程序编程接口。
一个字符串就是一连串的字符,字符串的处理在许多程序中都用得到。 Java 定义了 String 、StringBuffer、StringBuilder 等封装对字符串的各种操作。他们都被放到 java.lang 包中,不需要用 import java.lang 这个语句导入该包就可以直接使用他们。
String 类用于比较两个字符串,查找和抽取串中的字符或子串,进行字符串与其他类型之间的相互转换等。String 类对象的内容一旦被初始化就不能再改变。
StringBuffer 和 StringBuilder 类用于内容可以改变的字符串,可以将其他的各种类型数据增加、插入到字符串中,也可以转置字符串中原来的内容。一旦通过 StringBuffer和StringBuilder 生成了最终想要的字符串,就应该使用toString方法将其转化成 String 类,随后,就可以使用 String 类的各种方法操作这个字符串了。
String 示例
- public class Main {
-
- public static void main(String[] args) {
- String str = "Hello world";
- System.out.println(str);
- }
-
- }
StringBuffer和StringBuilder 示例
- public class Main {
-
- public static void main(String[] args) {
- StringBuffer stringBuffer = new StringBuffer();
- stringBuffer.append("hello ");
- stringBuffer.append("world");
- System.out.println(stringBuffer.toString());
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("hello ");
- stringBuilder.append("world");
- System.out.println(stringBuilder.toString());
- }
-
- }
在实际开中,如果频繁改变字符串的内容,就需要考虑使用 StringBuffer 和 StringBuilder ,因为其内容可以改变,执行性能相比 String 类更高。StringBuffer是线程安全的,如果不是在多线程下,建议使用 StringBuilder,性能相比之下好些。
Java 对数据提供基本数据的简单类型,也提供了 相应的包装类。使用基本数据类型,可以改善系统的性能,也能够满足大多数的应用需求。但是基本数据类不具有对象的特性,不能满足某些特殊的需求,从 JDK 中可以知道, Java 中的很多类的很多方法的参数类型都是 Object ,即这些方法接收的参数都是对象,同时,又需要用这些方法来处理基本类型的数据,这时就需要用到包装类。
Java 8 种基本数据类型对应的包装类型如下:
| 基本数据类型 | 基本数据类型包装类 |
| int | Integer |
| char | Character |
| float | Float |
| double | Double |
| byte | Byte |
| long | Long |
| short | Short |
| boolean | Boolean |
示例
- public class Main {
-
- public static void main(String[] args) {
-
- String ageStr = "18";
- int age = Integer.parseInt(ageStr);
- System.out.println(age);
-
- }
-
- }
Integer 类中的parseInt()方法,将一个字符串转化成基本数据类型。
Java 不支持全局方法和变量, Java 设计者将一些系统相关的重要的方法和变量收集到了一个同一的类中,这就是 System 类。System 类中的所有成员都是静态的,而要引用这些变量和方法,可直接使用 System 类作为前缀。
exit(int status) 方法,提前终止虚拟机的运行。若用户正常操作下终止虚拟机的运行,则传递零值作为参数。
CurrentTimeMillis 方法,返回自 1970 年 1月 1 日 0 点 0 秒起至今的以秒为单位的时间,这个是一个 long 类型的大数值,没有真正的日期类型以及其他各种类型,也就是说,平常用的日期实质上就是一个数值,但是通过这个数值,能够推算出其对应的具体日期时间。
getProperties 方法是获取当前虚拟机的环境属性。每一个属性都是变量与值以成对的形式出现。
Java 作为一个虚拟的操作系统,有自己的环境属性。Properties 是 Hashtable 的子类,用于存储 “变量/值” 对格式的数据,getProperties 方法返回值就是包含了当前虚拟机的所有环境属性的 Properties 类型的对象。
示例
-
- import java.util.Enumeration;
- import java.util.Properties;
-
- public class Main {
-
- public static void main(String[] args) {
-
- Properties p = System.getProperties();
- Enumeration e = p.propertyNames();
- while(e.hasMoreElements()){
- String key = (String)e.nextElement();
- System.out.println(key+"="+p.getProperty(key));
- }
-
- }
-
- }
控制台输出
- java.runtime.name=OpenJDK Runtime Environment
- java.vm.version=17.0.4.1+1
- sun.boot.library.path=D:\Program Files\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20220903-1038\jre\bin
- java.vm.vendor=Eclipse Adoptium
- java.vendor.url=https://adoptium.net/
- path.separator=;
- java.vm.name=OpenJDK 64-Bit Server VM
- sun.os.patch.level=
- user.script=
- user.country=CN
- sun.java.launcher=SUN_STANDARD
- java.vm.specification.name=Java Virtual Machine Specification
- user.dir=D:\eclipse-workspace\HelloWorld
- java.vm.compressedOopsMode=Zero based
- java.runtime.version=17.0.4.1+1
- os.arch=amd64
- java.io.tmpdir=C:\Users\64587\AppData\Local\Temp\
- line.separator=
-
- java.vm.specification.vendor=Oracle Corporation
- user.variant=
- os.name=Windows 11
- sun.jnu.encoding=GBK
- java.library.path=D:\Program Files\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20220903-1038\jre\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;D:/Program Files/eclipse//plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20220903-1038/jre/bin/server;D:/Program Files/eclipse//plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20220903-1038/jre/bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\Program Files\Java\jdk1.8.0_45\jre\bin;D:\Program Files\vmware\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;D:\tomcat\apache-tomcat-9.0.45\lib;D:\tomcat\apache-tomcat-9.0.45\bin;d:\Program Files\Git\cmd;D:\Program Files\TortoiseSVN\bin;;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;d:\Program Files (x86)\Tencent\微信web开发者工具\dll;C:\Program Files\nodejs\;C:\Users\64587\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\JetBrains\WebStorm 2022.1.1\bin;;C:\Users\64587\AppData\Roaming\npm;D:\Program Files\eclipse;;.
- jdk.debug=release
- java.class.version=61.0
- java.specification.name=Java Platform API Specification
- sun.management.compiler=HotSpot 64-Bit Tiered Compilers
- os.version=10.0
- user.home=C:\Users\64587
- file.encoding=UTF-8
- java.specification.version=17
- user.name=64587
- java.class.path=D:\eclipse-workspace\HelloWorld\bin
- java.vm.specification.version=17
- sun.arch.data.model=64
- sun.java.command=com.day04.Main
- java.home=D:\Program Files\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20220903-1038\jre
- user.language=zh
- java.specification.vendor=Oracle Corporation
- java.vm.info=mixed mode
- java.version=17.0.4.1
- native.encoding=GBK
- java.vendor=Eclipse Adoptium
- file.separator=\
- java.version.date=2022-08-12
- java.vendor.url.bug=https://github.com/adoptium/adoptium-support/issues
- sun.io.unicode.encoding=UnicodeLittle
- sun.cpu.endian=little
- java.vendor.version=Temurin-17.0.4.1+1
- sun.cpu.isalist=amd64
Runtime 封装了 Java 命令本身的运行进程,其中的许多方法与 System的方法重复。不能直接创建 Runtime 实例,但可以通过静态方法 Runtime.getRuntime() 获得正在运行的 Runtime 对象的引用。
Java 命令运行后,本身是多任务操作系统的上的一个进程,在这进程启动中启动一个新的进程执行其他程序时使用 exec 方法,exec 方法返回一个子代表子进程的 Process 类的对象,同过这个对象, Java 进程可以与子进程交互。
示例,Java 进程与子进程交互
- import java.io.IOException;
-
- public class Main {
-
- public static void main(String[] args) {
-
- Runtime r = Runtime.getRuntime();
- try {
- r.exec("notepad.exe");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- }
运行程序后,打开记事本程序。
Date 类用于表示日期和时间,最简单的构造方法是Date(),它以当前的日期和时间初始化一个Date 对象。由于开始设计 Date 时没有考虑到国际化,所以后来又设计了两个新的类来解决 Date 类中的问题,一个 Calendar 类,另一个是 DateFormat 类。
Calendar 类是一个抽象基类,主要完成日期字段之间相互操作的功能。如 Calendar.add 方法用于实现在某一日期的基础增加若干天(或年、月、小时、分、秒等日期字段)后的新日期,Calendar.get 方法用于取出日期对象中的年、月、日、小时、分、秒等日期字段的值, Calendar.set 方法用于修改日期对象中的年、月、日、小时、分、秒等日期字段的值。Calendar.getInstance 方法用于返回一个 Calendar 类型(更确切地说是它的某个子类)的对象实例,GregorianCalendar 类是 JDK 目前提供的一个唯一的 Calendar 子类,Calendar.getInstance 方法返回的就是预设了当前时间的 GregorianCalendar 类对象。
示例
- public class Main {
-
- public static void main(String[] args) {
-
- Calendar c1 = Calendar.getInstance();
- System.out.println(c1.get(c1.YEAR)+"年"+(c1.get(c1.MONTH)+1)+"月"+c1.get(c1.DAY_OF_MONTH)+"日"+c1.get(c1.HOUR_OF_DAY)+":"+c1.get(c1.MINUTE)+":"+c1.get(c1.SECOND));
- c1.add(c1.YEAR, 1);
- System.out.println(c1.get(c1.YEAR)+"年"+(c1.get(c1.MONTH)+1)+"月"+c1.get(c1.DAY_OF_MONTH)+"日"+c1.get(c1.HOUR_OF_DAY)+":"+c1.get(c1.MINUTE)+":"+c1.get(c1.SECOND));
- }
-
- }
控制台显示
- 2022年11月16日21:56:59
- 2023年11月16日21:56:59
需要注意的是月份需要加1,因为开始月份是0。
虽然 Calendar 类几乎完全替代了Date 类,但在某些情况下,开发者仍有可能用到 Date 类,譬如,程序中用的另外一个类的方法要求一个 Date 类型的参数。有时,要将 Date 对象表示的日期以指定的格式输出,或是将用特定格式显示的日期字符串转换成一个 Date 对象,而 java.text.DateFormat 就是实现这种功能的抽象基类。java.text.SimpleDateFormat 类就是 JDK 目前提供的一个 DateFormat 子类,它是一个具体类,具有把 Date 对象格式化为本地字符串,或者通过语义分析把日期或时间字符串转化为 Date 对象的功能。
示例
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- public class Main {
-
- public static void main(String[] args) {
-
- SimpleDateFormat sp1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
- SimpleDateFormat sp2 = new SimpleDateFormat("yyyy年MM月dd日 hh点mm分ss秒");
-
- try {
- Date date = sp1.parse("2014-6-18 18:30:38");
- System.out.println(sp2.format(date));
- } catch (ParseException e) {
- e.printStackTrace();
- }
- }
-
- }
SimpleDateFormat 类就相当于一个模板,其中 yyyy 是年,MM 对应的是月,dd 对应的是日 。
Math 类包含了所有用于几何和三角的浮点运算方法,这些方法都是静态的,每个方法的使用都非常的简单。
Random 类是一个随机生成器,随机数就是按照某种算法产生的,一旦用了一个初始值创建 Random 对象,就可以得到一系列的随机数。但是如果用相同的初始值创建 Random 对象,得到的随机数是相同的,也就是说, 在程序中看到的 "随机数" 是固定的那些数,起不到随机的作用。针对这个问题, Java 设计者在 Random 类的 Random 构造方法中使用当前的时间来初始化了 Random 对象,因为没有任何时刻时间是相同的,所以就可以减少随机数序列相同的可能性。
示例
- import java.util.Random;
-
- public class Main {
-
- public static void main(String[] args) {
-
- Random r = new Random();
- for (int i = 0; i < 5; i++) {
- System.out.println(r.nextInt(100)+"\t");
- }
-
- }
-
- }
示例
- public class Person {
- private String name;
- private Integer age;
- public Person(String name, Integer age) {
- super();
- this.name = name;
- this.age = age;
- }
-
- public static void main(String[] args) {
- Map<Object,String> map = new HashMap<Object,String>();
- map.put(new Person("张三", 18), "张三");
- System.out.println(map.get(new Person("张三", 18)));
- }
-
-
- }
运行这个程序,希望控制台显示 “张三”,但是实际返回一个 null 值,其原因就是没有重写 hashCode() 方法。
重新 hashcode 方法,就可以得到预期的效果
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Objects;
-
- public class Person {
- private String name;
- private Integer age;
- public Person(String name, Integer age) {
- super();
- this.name = name;
- this.age = age;
- }
-
-
- @Override
- public int hashCode() {
- return Objects.hash(age, name);
- }
-
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Person other = (Person) obj;
- return Objects.equals(age, other.age) && Objects.equals(name, other.name);
- }
-
-
- public static void main(String[] args) {
- Map<Object,String> map = new HashMap<Object,String>();
- map.put(new Person("张三", 18), "张三");
- System.out.println(map.get(new Person("张三", 18)));
- }
-
-
- }
对象克隆(clone)实际上是将一个对象重新复制一份。在 Java 里提到的 clone 技术,就是不能不提到 java .lang.Cloneable 接口和含有 clone 方法的 Object 类,所有具有 clone 功能的类都有一个特性,那就是它直接或间接的时间了 Cloneable 接口。否则,在尝试调用 clone() 方法,将会触发 CloneNotSupportedException 异常。
示例
- public class Person implements Cloneable {
- private String name;
- private Integer age;
- public Person(String name, Integer age) {
- super();
- this.name = name;
- this.age = age;
- }
-
-
-
- public String getName() {
- return name;
- }
-
-
-
- public void setName(String name) {
- this.name = name;
- }
-
-
-
- public Integer getAge() {
- return age;
- }
-
-
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
-
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + "]";
- }
-
-
-
- public static void main(String[] args) {
- Person p1 = new Person("张三",23);
- Person p2 = null;
- try {
- p2 = (Person) p1.clone();
- p2.setName("李四");
- p2.setAge(28);
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
-
- System.out.println(p1);
- System.out.println(p2);
- }
-
-
- }
控制台显示
- Person [name=张三, age=23]
- Person [name=李四, age=28]