原文:Java 语言基础 (常用类的概述和使用, String 类的概述和使用, 可变字符串类和日期相关类, 集合类库)
常用类的概述和使用
常用的包
包的名称和功能
java.lang
包 - java 语言的核心包, 并且该包的所有内容由 java 虚拟机自动导入. 如: System
类, String
类, ...
java.util
包 - Java 语言的工具包,里面提供了大量工具类以及集合类等。如:Scanner
类、Random
类、List
集合、...
java.io
包 - Java 语言中的输入输出包,里面提供了大量读写文件相关的类等。如:FileInputStream
类、FileOutputStream
类、...
java.net
包 - Java 语言中的网络包,里面提供了大量网络编程相关的类等。如:ServerSocket
类、Socket
类、...
java.sql
包 - Java 语言中的数据包,里面提供了大量操作数据库的类和接口等。如:DriverManager
类、Connection
接口、…
... ...
虽然 Java 编程时需要记的很多,但是因为 Java 程序员在编程时可以使用大量类库,所以对编程能力本身要求不是特别的高。
Object
类的概述
基本概念
java.lang.Object
类是 Java 语言中类层次结构的根类,也就是说任何一个类都是该类的直接或者间接子类。
如果定义一个 Java 类时没有使用 extends
关键字声明其父类,则其父类为 java.lang.Object
类。
Object
类定义了“对象”的基本行为,被子类默认继承。
常用方法
方法声明 | 功能介绍 |
---|---|
Object() |
使用无参方式构造对象。 |
boolean equals(Object obj) |
用于判断调用对象是否与参数对象相等。该方法默认比较两个对象的地址是否相等,与 == 运算符的结果一致。若希望比较两个对象的内容,则需要重写该方法。若该方法被重写后,则应该重写 hashCode 方法来保证结果的一致性。 |
int hashCode() |
用于获取调用对象的哈希码值(内存地址的编号)。若两个对象调用 equals 方法相等,则各自调用该方法的结果必须相同。若两个调用对象equals 方法不相等,则各自调用该方法的结果应该不相同。为了使得该方法与 equals 方法保持一致,需要重写该方法。 |
String toString() |
用于获取调用对象的字符串形式。该方法默认返回的字符串为:包名.类名@哈希码值的十六进制 。为了返回更有意义的数据,需要重写该方法。使用 print 或 println 打印引用或字符串拼接引用都会自动调用该方法。 |
Class> getClass() |
用于返回调用对象执行时的 Class 实例,反射机制使用。 |
想了解更多,欢迎关注我的微信公众号:Renda_Zhang
包装类
概念
基本数据类型转换为对应包装类的方式:调用包装类的构造方法或静态方法即可。
获取包装类对象中基本数据类型变量数值的方式: 调用包装类中的 xxxValue
方法即可。
字符串转换为基本数据类型的方式: 调用包装类中的 parseXxx
方法即可。
在 Byte, Short, Integer, Long, Character, Boolean
类的内部提供了常量池技术。
整型的包装类将 -128
到 127
之间的整数已经装箱完毕,当程序中使用该范围之间的整数时,无需装箱直接取用常量池中的对象即可,从而提高效率。
浮点类型的包装类可以自动装箱, 但是没有实现常量池技术, 所以每次创建的对象都不一样。
可以通过 JVM 的 -XX:AutoBoxCacheMax =
来控制整数范围。
在 Java 5 发布之前使用包装类对象进行运算时,需要较为繁琐的“拆箱”和“装箱”操作;即运算前先将包装类对象拆分为基本类型数据,运算后再将结果封装成包装类对象。
从 Java 5 开始增加了自动拆箱和自动装箱的功能。
通常情况下基本数据类型的变量不是对象,为了满足万物皆对象的理念就需要对基本数据类型的变量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象化处理的相关类,叫做包装类 (Wrapper)。
如:
Person p = new Person();
int num = 10;
Integer numInteger = Integer.valueOf(num);
装箱和拆箱的概念
自动装箱 和 常量池
使用总结
分类
包装类 | 对应的基本类型 |
---|---|
java.lang.Byte |
byte |
java.lang.Short |
short |
java.lang.Integer |
int |
java.lang.Long |
long |
java.lang.Float |
float |
java.lang.Double |
double |
java.lang.Boolean |
boolean |
java.lang.Character |
char |
Integer
类的概述
java.lang.Integer
类内部包装了一个 int
类型的变量作为成员变量,主要用于实现对 int
类型的包装并提供 int
类型到 String
类之间的转换等方法。
基本概念
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int MAX_VALUE |
表示 int 类型可以描述的最大值,即 2^31-1 |
public static final int MIN_VALUE |
表示 int 类型可以描述的最小值,即 -2^31 |
public static final int SIZE |
表示 int 类型采用二进制补码形式的位数 |
public static final int BYTES |
表示 int 类型所占的字节个数 |
public static final Class TYPE |
表示 int 类型的 Class 实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Integer(int value) |
根据参数指定的整数来构造对象(已过时) |
Integer(String s) |
根据参数指定的字符串来构造对象 (已过时) |
int intValue() |
获取调用对象中的整数值并返回 |
static Integer valueOf(int i) |
根据参数指定整数值得到 Integer 类型对象 |
boolean equals(Object obj) |
比较调用对象与参数指定的对象是否相等 |
String toString() |
返回描述调用对象数值的字符串形式 |
static int parseInt(String s) |
将字符串类型转换为 int 类型并返回 |
static String toString(int i) |
获取参数指定整数的十进制字符串形式 |
static String toBinaryString(int i) |
获取参数指定整数的二进制字符串形式 |
static String toHexString(int i) |
获取参数指定整数的十六进制字符串形式 |
static String toOctalString(int i) |
获取参数指定整数的八进制字符串形式 |
Double
类的概述
java.lang.Double
类型内部包装了一个 double
类型的变量作为成员变量,主要用于实现对 double
类型的包装并提供 double
类型到 String
类之间的转换等方法。
基本概念
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE |
表示double 类型的二进制位数 |
public static final int BYTES |
表示double 类型的字节个数 |
public static final Class TYPE |
表示double 类型的Class 实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Double(double value) |
根据参数指定的浮点数据来构造对象(已过时) |
Double(String s) |
根据参数指定的字符串来构造对象 (已过时) |
double doubleValue() |
获取调用对象中的浮点数据并返回 |
static Double valueOf(double d) |
根据参数指定浮点数据得到Double 类型对象 |
boolean equals(Object obj) |
比较调用对象与参数指定的对象是否相等 |
String toString() |
返回描述调用对象数值的字符串形式 |
static double parseDouble(String s) |
将字符串类型转换为double 类型并返回 |
boolean isNaN() |
判断调用对象的数值是否为非数字 |
扩展:java.lang.Number
类是个抽象类,是上述类的父类来描述所有类共有的成员。
Boolean
类的概述
java.lang.Boolean
类型内部包装了一个boolean
类型的变量作为成员变量,主要用于实现对boolean
类型的包装并提供boolean
类型到String
类之间的转换等方法。
基本概念
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final Boolean FALSE |
对应基值为false 的对象 |
public static final Boolean TRUE |
对应基值为true 的对象 |
public static final Class TYPE |
表示boolean 类型的Class 实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Boolean(boolean value) |
根据参数指定的布尔数值来构造对象(已过时) |
Boolean(String s) |
根据参数指定的字符串来构造对象 (已过时) |
boolean booleanValue() |
获取调用对象中的布尔数值并返回 |
static Boolean valueOf(boolean b) |
根据参数指定布尔数值得到Boolean 类型对象 |
boolean equals(Object obj) |
比较调用对象与参数指定的对象是否相等 |
String toString() |
返回描述调用对象数值的字符串形式 |
String toString() |
将字符串类型转换为boolean 类型并返回 |
Character
类的概述
java.lang.Character
类型内部包装了一个 char
类型的变量作为成员变量,主要用于实现对 char
类型的包装并提供字符类别的判断和转换等方法。
基本概念
常用的常量
常量类型和名称 | 功能介绍 |
---|---|
public static final int SIZE |
表示 char 类型的二进制位数 |
public static final int BYTES |
表示 char 类型的字节个数 |
public static final Class TYPE |
表示 char 类型的 Class 实例 |
常用的方法
方法声明 | 功能介绍 |
---|---|
Character(char value) |
根据参数指定的字符数据来构造对象(已过时) |
char charValue() |
获取调用对象中的字符数据并返回 |
static Character valueOf(char c) |
根据参数指定字符数据得到 Character 类型对象 |
boolean equals(Object obj) |
比较调用对象与参数指定的对象是否相等 |
String toString() |
返回描述调用对象数值的字符串形式 |
static boolean isUpperCase(char ch) |
判断参数指定字符是否为大写字符 |
static boolean isLowerCase(char ch) |
判断参数指定字符是否为小写字符 |
static boolean isDigit(char ch) |
判断参数指定字符是否为数字字符 |
static char toUpperCase(char ch) |
将参数指定的字符转换为大写字符 |
static char toLowerCase(char ch) |
将参数指定的字符转换为小写字符 |
数学处理类
Math
类的概述
java.lang.Math
类主要用于提供执行数学运算的方法,如:对数,平方根。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static int max(int a, int b) |
返回两个参数中的最大值 |
static int min(int a, int b) |
返回两个参数中的最小值 |
static double pow(double a, double b) |
返回第一个参数的幂 |
static int abs(int a) |
返回参数指定数值的绝对值 |
static long round(double a) |
返回参数四舍五入的结果 |
static double sqrt(double a) |
返回参数的平方根 |
static double random() |
返回 0.0 到 1.0 的随机数 |
BigDecimal
类的概述
由于 float
类型和 double
类型在运算时可能会有误差,若希望实现精确运算则借助 java.math.BigDecimal
类型加以描述。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
BigDecimal(String val) |
根据参数指定的字符串来构造对象 |
BigDecimal add(BigDecimal augend) |
用于实现加法运算 |
BigDecimal subtract(BigDecimal subtrahend) |
用于实现减法运算 |
BigDecimal multiply(BigDecimal multiplicand) |
用于实现乘法运算 |
BigDecimal divide(BigDecimal divisor) |
用于实现除法运算 |
BigInteger
类的概念
若希望表示比 long
类型范围还大的整数数据,则需要借助 java.math.BigInteger
类型描述。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
BigInteger(String val) |
根据参数指定的字符串来构造对象 |
BigInteger add(BigInteger val) |
用于实现加法运算 |
BigInteger subtract(BigInteger val) |
用于实现减法运算 |
BigInteger multiply(BigInteger val) |
用于实现乘法运算 |
BigInteger divide(BigInteger val) |
用于实现除法运算 |
BigInteger remainder(BigInteger val) |
用于实现取余运算 |
BigInteger[] divideAndRemainder(BigInteger val) |
用于实现取商和余数的运算 |
String
类的概述和使用
String类的概念
java.lang.String
类用于描述字符串,Java 程序中所有的字符串字面值都可以使用该类的对象加以描述,如:"abc"
。
该类由 final
关键字修饰,表示该类不能被继承。
从 jdk 1.9
开始该类的底层不使用 char[]
来存储数据,而是改成 byte[]
加上编码标记,从而节约了一些空间。
该类描述的字符串内容是个常量不可更改,因此可以被共享使用。如:
将 “123”
字符串的地址赋值给变量 str1
改变 str1
的指向并没有改变指向的内容
其中 "abc"
这个字符串是个常量不可改变
String str1 = “abc”;
str1 = “123”;
常量池的概念
由于 String
类型描述的字符串内容是常量不可改变,因此 Java 虚拟机将首次出现的字符串放入常量池中,若后续代码中出现了相同字符串内容则直接使用池中已有的字符串对象而无需申请内存及创建对象,从而提高了性能。
常用的构造方法
方法声明 | 功能介绍 |
---|---|
String() |
使用无参方式构造对象得到空字符序列 |
String(byte[] bytes, int offset, int length) |
使用 bytes 数组中下标从 offset 位置开始的 length 个字节来构造对象 |
String(byte[] bytes) |
使用 bytes 数组中的所有内容构造对象 |
String(char[] value, int offset, int count) |
使用value数组中下标从 offset 位置开始的 count 个字符来构造对象 |
String(char[] value) |
使用 value 数组中的所有内容构造对象 |
String(String original) |
根据参数指定的字符串内容来构造对象,新创建对象为参数对象的副本 |
常用的成员方法
方法声明 (表格一) | 功能介绍 |
---|---|
String toString() |
返回字符串本身 |
byte[] getBytes() |
将当前字符串内容转换为 byte 数组并返回 |
char[] toCharArray() |
用于将当前字符串内容转换为 char 数组并返回 |
char charAt(int index) |
方法 charAt 用于返回字符串指定位置的字符。 |
int length() |
返回字符串字符序列的长度 |
boolean isEmpty() |
判断字符串是否为空 |
方法声明 (表格二) | 功能介绍 |
---|---|
int compareTo(String anotherString) |
用于比较调用对象和参数对象的大小关系 |
int compareToIgnoreCase(String str) |
不考虑大小写,也就是 'a' 和 'A' 是相等的关系 |
方法声明 (表格三) | 功能介绍 |
---|---|
String concat(String str) |
用于实现字符串的拼接 |
boolean contains(CharSequence s) |
用于判断当前字符串是否包含参数指定的内容 |
String toLowerCase() |
返回字符串的小写形式 |
String toUpperCase() |
返回字符串的大写形式 |
String trim() |
返回去掉前导和后继空白的字符串 |
boolean startsWith(String prefix) |
判断字符串是否以参数字符串开头 |
boolean startsWith(String prefix, int toffset) |
从指定位置开始是否以参数字符串开头 |
boolean endsWith(String suffix) |
判断字符串是否以参数字符串结尾 |
方法声明 (表格四) | 功能介绍 |
---|---|
boolean equals(Object anObject) |
用于比较字符串内容是否相等并返回 |
int hashCode() |
获取调用对象的哈希码值 |
boolean equalsIgnoreCase(String anotherString) |
用于比较字符串内容是否相等并返回,不考虑大小写,如:'A' 和 'a' 是相等 |
方法声明 (表格五) | 功能介绍 |
---|---|
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 位置开始反向搜索的第一次出现的下标 |
方法声明 (表格六) | 功能介绍 |
---|---|
String substring(int beginIndex, int endIndex) |
返回字符串中从下标 beginIndex (包括)开始到 endIndex (不包括)结束的子字符串 |
String substring(int beginIndex) |
返回字符串中从下标 beginIndex (包括)开始到字符串结尾的子字符串 |
正则表达式的概念
正则表达式本质就是一个“规则字符串”,可以用于对字符串数据的格式进行验证,以及匹配、查找、替换等操作。该字符串通常使用 ^
运算符作为开头标志,使用 $
运算符作为结尾标志,当然也可以省略。
正则表达式的规则
正则表达式 (表格一) | 说明 |
---|---|
[abc] |
可以出现 a、b、c 中任意一个字符 |
[^abc] |
可以出现任何字符,除了 a、b、c 的任意字符 |
[a-z] |
可以出现 a、b、c、……、z 中的任意一个字符 |
[a-zA-Z0-9] |
可以出现 a~z、A~Z、0~9 中任意一个字符 |
正则表达式 (表格二) | 说明 |
---|---|
. |
任意一个字符(通常不包含换行符) |
\d |
任意一个数字字符,相当于[0-9] |
\D |
任意一个非数字字符 |
\s |
空白字符,相当于[\t\n\x0B\f\r] |
\S |
非空白字符 |
\w |
任意一个单词字符,相当于[a-zA-Z_0-9] |
\W |
任意一个非单词字符 |
正则表达式 (表格三) | 说明 |
---|---|
X? |
表示 X 可以出现一次或一次也没有,也就是 0 ~ 1 次 |
X* |
表示 X 可以出现零次或多次,也就是 0 ~ n 次 |
X+ |
表示 X 可以出现一次或多次,也就是 1 ~ n 次 |
X{n} |
表示X可以出现恰好 n 次 |
X{n,} |
表示X可以出现至少 n 次,也就是 >=n 次 |
X{n,m} |
表示X可以出现至少 n 次,但是不超过 m 次,也就是 >=n 并且 <=m 次 |
正则表达式相关的方法
方法名称 (表格一) | 方法说明 |
---|---|
boolean matches(String regex) |
判断当前正在调用的字符串是否匹配参数指定的正则表达式规则 |
方法名称 (表格二) | 方法说明 |
---|---|
String[] split(String regex) |
参数 regex 为正则表达式,以 regex 所表示的字符串为分隔符,将字符串拆分成字符串数组 |
String replace(char oldChar, char newChar) |
使用参数 newChar 替换此字符串中出现的所有参数 oldChar |
String replaceFirst(String regex, String replacement) |
替换此字符串匹配给定的正则表达式的第一个子字符串 |
String replaceAll(String regex, String replacement) |
将字符串中匹配正则表达式 regex 的字符串替换成 replacement |
可变字符串类和日期相关类
可变字符串类
基本概念
由于String
类描述的字符串内容是个常量不可改变,当需要在 Java 代码中描述大量类似的字符串时,只能单独申请和存储,此时会造成内存空间的浪费。
为了解决上述问题,可以使用 java.lang.StringBuilder
类和java.lang.StringBuffer
类来描述字符序列可以改变的字符串,如:"ab"
。
StringBuffer
类是从jdk 1.0
开始存在,属于线程安全的类,因此效率比较低。
StringBuilder
类是从 jdk 1.5
开始存在,属于非线程安全的类,效率比较高。
当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量 << 1 + 2 = 原始容量 * 2 + 2
一般执行效率:StringBuilder > StringBuffer > String
StringBuilder
类常用的构造方法
方法声明 | 功能介绍 |
---|---|
StringBuilder() |
使用无参方式构造对象,容量为 16 |
StringBuilder(int capacity) |
根据参数指定的容量来构造对象,容量为参数指定大小 |
StringBuilder(String str) |
根据参数指定的字符串来构造对象,容量为:16 + 字符串长度 |
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) |
删除字符串 |
StringBuilder replace(int start,int end, String str) |
替换字符串 |
StringBuilder reverse() |
字符串反转 |
作为参数传递的话,方法内部 String
不会改变其值,StringBuffer
和 StringBuilder
会改变其值。
StringBuffer
和 StringBuilder
返回调用对象自己的引用,也就是返回值和调用对象是同一个字符串。
返回值的设计
StringBuilder
的很多方法的返回值均为 StringBuilder
类型。这些方法的返回语句均为:return this
。
由此可见,这些方法在对 StringBuilder
所封装的字符序列进行改变后又返回了该对象的引用。基于这样设计的目的在于可以连续调用。如:str.reverse().append("1");
Java 8 之前的日期相关类
System
类的概述
Java.lang.System
类中提供了一些有用的类字段和方法。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static long currentTimeMillis() |
返回当前时间与 1970 年 1 月 1 日 0 时 0 分 0 秒之间以毫秒为单位的时间差 |
Date
类的概述
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 毫秒的时间点 |
SimpleDateFormat
类的概述
java.text.SimpleDateFormat
类主要用于实现日期和文本之间的转换。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
SimpleDateFormat() |
使用无参方式构造对象 |
SimpleDateFormat(String pattern) |
根据参数指定的模式来构造对象,模式主要有: y-年 M-月 d-日 H-时 m-分 s-秒 |
final String format(Date date) |
用于将日期类型转换为文本类型 |
Date parse(String source) |
用于将文本类型转换为日期类型 |
Calendar
类的概述
通过方法的参数传递形成多态;
public static void draw(Shape s){
s.show();
}
draw(new Rect(1, 2, 3, 4));
在方法体中直接使用多态的语法格式
Account acc = new FixedAccount();
通过方法的返回值类型形成多态
Calender getInstance(){
return new GregorianCalendar(zone, aLocale);
}
java.util.Calender
类主要用于描述特定的瞬间,取代 Date
类中的过时方法实现全球化。
该类是个抽象类,因此不能实例化对象,其具体子类针对不同国家的日历系统,其中应用最广泛的是 GregorianCalendar
(格里高利历),对应世界上绝大多数国家/地区使用的标准日历系统。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static Calendar getInstance() |
用于获取 Calendar 类型的引用,返回的并不是Calendar类型的对象,而是Calendar类的子类GregorianCalendar等对象 |
void set(int year, int month, int date, int hourOfDay, int minute, int second) |
用于设置年月日时分秒信息 |
Date getTime() |
用于将 Calendar 类型转换为 Date 类型 |
void set(int field, int value) |
设置指定字段的数值 |
void add(int field, int amount) |
向指定字段增加数值 |
多态的使用场合
Java 8 中的日期相关类
Java 8 日期类的由来
JDK 1.0
中包含了一个 java.util.Date
类,但是它的大多数方法已经在 JDK 1.1
引入Calendar
类之后被弃用了。而 Calendar
并不比 Date
好多少。它们面临的问题是:
Date
类中的年份是从 1900
开始的,而月份都从 0
开始。
格式化只对 Date
类有用,对 Calendar
类则不能使用。
非线程安全等。
Java 8 日期类的概述
Java 8 通过发布新的 Date-Time API
来进一步加强对 日期与时间的处理。
java.time
包:该包日期/时间API的基础包。
java.time.chrono
包:该包提供对不同日历系统的访问。
java.time.format
包:该包能够格式化和解析日期时间对象。
java.time.temporal
包:该包包含底层框架和扩展特性。
java.time.zone
包:该包支持不同时区以及相关规则的类。
LocalDate
类的概述
java.time.LocalDate
类主要用于描述年-月-日格式的日期信息,该类不表示时间和时区信息。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalDate now() |
在默认时区中从系统时钟获取当前日期 |
LocalTime
类的概述
java.time.LocalTime
类主要用于描述时间信息,可以描述时分秒以及纳秒。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalTime now() |
从默认时区的系统时间中获取当前时间 |
static LocalTime now(ZoneId zone) |
获取指定时区的当前时间 |
LocalDateTime
类的概述
java.time.LocalDateTime
类主要用于描述 ISO-8601
日历系统中没有时区的日期时间,如2007-12-03T10:15:30
。
与 String
类型相似,调用对象本身的数据内容不会改变,返回值相当于创建了一个新的对象,由此证明了不可变性。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static LocalDateTime now() |
从默认时区的系统时间中获取当前日期时间 |
static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second) |
根据参数指定的年月日时分秒信息来设置日期时间 |
int getYear() |
获取年份字段的数值 |
int getMonthValue() |
获取 1 到 12 之间的月份字段 |
int getDayOfMonth() |
获取日期字段 |
int getHour() |
获取小时数 |
int getMinute() |
获取分钟数 |
int getSecond() |
获取秒数 |
LocalDateTime withYear(int year) |
设置为参数指定的年 |
LocalDateTime withMonth(int month) |
设置为参数指定的月 |
LocalDateTime withDayOfMonth(int dayOfMonth) |
设置为参数指定的日 |
LocalDateTime withHour(int hour) |
设置为参数指定的时 |
LocalDateTime withMinute(int minute) |
设置为参数指定的分 |
LocalDateTime withSecond(int second) |
设置为参数指定的秒 |
LocalDateTime plusYears(long years) |
加上参数指定的年 |
LocalDateTime plusMonths(long months) |
加上参数指定的月 |
LocalDateTime plusDays(long days) |
加上参数指定的日 |
LocalDateTime plusHours(long hours) |
加上参数指定的时 |
LocalDateTime plusMinutes(long minutes) |
加上参数指定的分 |
LocalDateTime plusSeconds(long seconds) |
加上参数指定的秒 |
LocalDateTime minusYears(long years) |
减去参数指定的年 |
LocalDateTime minusMonths(long months) |
减去参数指定的月 |
LocalDateTime minusDays(long days) |
减去参数指定的日 |
LocalDateTime minusHours(long hours) |
减去参数指定的时 |
LocalDateTime minusMinutes(long minutes) |
减去参数指定的分 |
LocalDateTime minusSeconds(long seconds) |
减去参数指定的秒 |
Instant
类的概述
java.time.Instant
类主要用于描述瞬间的时间点信息,可以精确到纳秒。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static Instant now() |
从系统时钟上获取当前时间,并不是当前系统的默认时区 |
OffsetDateTime atOffset(ZoneOffset offset) |
将此瞬间与偏移量组合以创建偏移日期时间 |
static Instant ofEpochMilli(long epochMilli) |
根据参数指定的毫秒数来构造对象,参数为距离 1970 年 1 月 1 日 0 时 0 分 0 秒的毫秒数 |
long toEpochMilli() |
获取距离 1970 年 1 月 1 日 0 时 0 分 0 秒的毫秒数 |
DateTimeFormatter
类的概述
java.time.format.DateTimeFormatter
类主要用于格式化和解析日期。
基本概念
常用的方法
方法声明 | 功能介绍 |
---|---|
static DateTimeFormatter ofPattern(String pattern) |
根据参数指定的模式来获取对象 |
String format(TemporalAccessor temporal) |
将参数指定日期时间转换为字符串 |
TemporalAccessor parse(CharSequence text) |
将参数指定字符串转换为日期时间 |
集合类库 (上)
集合的概述
集合的由来
记录单个数据内容时,则声明一个变量。
记录多个类型相同的数据内容时,声明一个一维数组。
记录多个类型不同的数据内容时,则创建一个对象。
记录多个类型相同的对象数据时,创建一个对象数组。
记录多个类型不同的对象数据时,则准备一个集合。
集合的框架结构
Java 中 Collections
是工具类,提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
Java 中集合框架顶层框架是:java.util.Collection
集合和 java.util.Map
集合。
其中 Collection
集合中存取元素的基本单位是:单个元素。
其中 Map
集合中存取元素的基本单位是:单对元素。
Collection
集合
基本概念
java.util.Collection
接口是List接口、Queue
接口以及 Set
接口的父接口,因此该接口里定义的方法既可用于操作 List
集合,也可用于操作 Queue
集合和 Set
集合。
打印集合中的所有元素时,本质上就是打印集合中的每个对象,也就是让每个对象调用对应类的 toString
方法。
contains
方法的工作原理是:Objects.equals(o, e)
,其中 o
代表 contains
方法的形式参数,e
代表集合中的每个元素。也就是 contains
的工作原理就是拿着参数对象与集合中已有的元素依次进行比较,比较的方式调用 Objects
中的 equals
方法。如果 o
是对象且没有重写 equals
方法时,比较的是地址,则为 false;如果重写了 equals
方法时,比较的是内容,则为 true
。
c1.contains(c2)
判断集合 c1
中是否拥有集合 c2
这个整体为单位的元素。c1.containsAll(c3)
判断集合 c1
中是否包含集合 c3
中的所有元素,只有集合 c3
中的所有元素都在集合 c1
中出现才会返回 true
,否则都是 false
。
remove
方法删除对象 o
的源码调用了Objects.equals(o, e)
,所以 o
是否重写了 equals
方法会影响到判断。
c1.remove(c2)
删除整体对象 c2
。c1.removeAll(c3)
从集合 c1
中删除集合 c3
中的所有元素,本质上就是一个一个元素进行删除,有元素则删除,否则不删除。
实现数组类型到集合类型的转换:
Collection collection = Arrays.asList(array);
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean add(E e) |
向集合中添加对象 |
boolean addAll(Collection extends E> c) |
用于将参数指定集合 c 中的所有元素添加到当前集合中 |
boolean contains(Object o) |
判断是否包含指定对象 |
boolean containsAll(Collection> c) |
判断是否包含参数指定的所有对象 |
boolean retainAll(Collection> c) |
保留当前集合中存在且参数集合中存在的所有对象 |
boolean remove(Object o) |
从集合中删除对象 |
boolean removeAll(Collection> c) |
从集合中删除参数指定的所有对象 |
void clear() |
清空集合 |
int size() |
返回包含对象的个数 |
boolean isEmpty() |
判断是否为空 |
boolean equals(Object o) |
判断是否相等 |
int hashCode() |
获取当前集合的哈希码值 |
Object[] toArray() |
将集合转换为数组 |
Iterator iterator() |
获取当前集合的迭代器 |
Iterator
接口
基本概念
java.util.Iterator
接口主要用于描述迭代器对象,可以遍历 Collection
集合中的所有元素。
java.util.Collection
接口继承 Iterator
接口,因此所有实现 Collection
接口的实现类都可以使用该迭代器对象。
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean hasNext() |
判断集合中是否有可以迭代/访问的元素 |
E next() |
用于取出一个元素并指向下一个元素 |
void remove() |
用于删除访问到的最后一个元素 |
for each 循环
基本概念
Java 5 推出了增强型 for
循环语句,可以应用数组和集合的遍历。
是经典迭代的“简化版”。
语法格式
for (元素类型 变量名 : 数组/集合名称) {
循环体;
}
执行流程
不断地从数组/集合中取出一个元素赋值给变量名并执行循环体,直到取完所有元素为止。
List 集合
基本概念
java.util.List
集合是 Collection
集合的子集合,该集合中允许有重复的元素并且有先后放入次序。
该集合的主要实现类有:ArrayList
类、LinkedList
类、Stack
类、Vector
类。
其中 ArrayList
类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。
其中 LinkedList
类的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便。
可以认为 ArrayList
和 LinkedList
的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList
更适合于随机访问而 LinkedList
更适合于插入和删除;在性能要求不是特别苛刻的情形下可以忽略这个差别。
其中 Stack
类的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的数据结构,叫做栈 (Last In First Out, LIFO)。
其中 Vector
类的底层是采用动态数组进行数据管理的,该类与 ArrayList
类相比属于线程安全的类,效率比较低,以后开发中基本不用。
常用的方法
方法声明 | 功能介绍 |
---|---|
void add(int index, E element) |
向集合中指定位置添加元素 |
boolean addAll(int index, Collection extends E> c) |
向集合中添加所有元素 |
E get(int index) |
从集合中获取指定位置元素 |
int indexOf(Object o) |
查找参数指定的对象 |
int lastIndexOf(Object o) |
反向查找参数指定的对象 |
E set(int index, E element) |
修改指定位置的元素 |
E remove(int index) |
删除指定位置的元素 |
List subList(int fromIndex, int toIndex) |
用于获取子 List ,子集合和当前集合共用同一块内存空间 |
Queue集合
基本概念
java.util.Queue
集合是 Collection
集合的子集合,与 List 集合属于平级关系。
该集合的主要用于描述具有先进先出特征的数据结构,叫做队列 (first in first out, FIFO)。
该集合的主要实现类是 LinkedList
类,因为该类在增删方面比较有优势。
常用的方法
方法声明 | 功能介绍 |
---|---|
boolean offer(E e) |
将一个对象添加至队尾,若添加成功则返回 true |
E poll() |
从队首删除并返回一个元素 |
E peek() |
返回队首的元素(但并不删除) |
集合类库 (下)
泛型机制
基本概念
通常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做 Object
类型放入的,因此从集合中取出元素时也是 Object
类型,为了表达该元素真实的数据类型,则需要强制类型转换,而强制类型转换可能会引发类型转换异常。
为了避免上述错误的发生,从 Java 5 开始增加泛型机制,也就是在集合名称的右侧使用 <数据类型>
的方式来明确要求该集合中可以存放的元素类型,若放入其它类型的元素则编译报错。
泛型只在编译时期有效,在运行时期不区分是什么类型。
Java 7 开始的新特性“菱形特性”,就是后面<>中的数据类型可以省略:
List
底层原理
泛型的本质就是参数化类型,也就是让数据类型作为参数传递,其中 E
相当于形式参数负责占位,而使用集合时 <>
中的数据类型相当于实际参数,用于给形式参数 E
进行初始化,从而使得集合中所有的 E
被实际参数替换,由于实际参数可以传递各种各样广泛的数据类型,因此得名为泛型。
对比方法传参和泛型:
方法传参例子
// i 叫做形式参数,负责占位
public static void show(int i) {
...
}
// 其中 10 叫做实际参数,负责给形式参数初始化;int i = 10; int i = 20;
show(10);
show(20);
泛型例子
// E 叫做形式参数,负责占位
public interface List{
...
}
// 其中 String 叫做实际参数;E = String; E = Integer;
Listlt1 = ...;
Listlt2 = ...;
自定义泛型接口
泛型接口和普通接口的区别就是后面添加了类型参数列表,可以有多个类型参数,如:
等。
自定义泛型类
泛型类和普通类的区别就是类名后面添加了类型参数列表,可以有多个类型参数,如:
等。
实例化泛型类时应该指定具体的数据类型,并且是引用数据类型而不是基本数据类型。
父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型。如果子类保留父类的泛型 T
,则可以在构造对象时来指定 T
的类型。如果子类没有保留父类泛型 T
且没有指定泛型,则父类的泛型 T
默认为 Object
类型。
子类除了指定或保留父类的泛型,还可以增加自己的泛型。
自定义泛型方法
泛型方法就是我们输入参数的时候,输入的是泛型参数,而不是具体的参数。我们在调用这个泛型方法的时需要对泛型参数进行实例化。所以,以下的自定义泛型类中的方法不属于泛型方法,而且它们不能使用 static
关键字修饰,因为该方法中的 T
需要在 new
对象时才能明确类型:
// 泛型类
public class Person{
private E gender;
// 非泛型方法,不能使用 static
public E getGender() {
return gender;
}
// 非泛型方法,不能使用 static
public void setGender(E gender) {
this.gender = gender;
}
}
在静态方法中使用泛型参数的时候,需要把静态方法定义为泛型方法。以下为在泛型类中的静态泛型方法的例子:
public class Person{
public staticvoid printArray(T[] arr) {
for (T v: arr) {
System.out.println(v);
}
}
}
调用泛型方法:
Integer[] arr = {11, 22, 33, 44, 55};
Person.printArray(arr); // 11 22 33 44 55
泛型方法的格式:[访问权限] <泛型> 返回值类型 方法名([泛型标识 参数名称]) { 方法体; }
泛型在继承上的体现
通配符的使用
>
无限制通配符:表示我们可以传入任意类型的参数。
extends E>
表示类型的上界是 E
,只能是 E
或者是 E
的子类。
List extends Number> lt4 = new LinkedList<>();
// 不支持元素的添加操作
// 获取元素
Number number = lt4.get(0);
super E>
表示类型的下界是 E
,只能是 E
或者是 E
的父类。
List super Number> lt5 = new LinkedList<>();
lt5.add(new Number());
lt5.add(new Integer());
// lt5.add(new Object()); Error: 超过了 Number 类型的范围
Object object = lt5.get(0);
如果希望控制传入的类型在一个指定的范围内,可以使用泛型通配符 。
如:之前传入的类型要求为 Integer
类型,但是后来业务需要 Integer
的父类Number
类也可以传入。
泛型中有三种通配符形式:
Listlt1 = new LinkedList<>();
Listlt2 = new LinkedList<>();
List> lt3 = new LinkedList<>();
// 不支持元素的添加操作, 如 lt3.add(new Number());
// 支持元素的获取操作,全部当做Object类型来处理
// 可以发生List类型到List>类型的转换
lt3 = lt1;
// 可以发生List类型到List>类型的转换
lt3 = lt2;
Set 集合
基本概念
java.util.Set
集合是 Collection
集合的子集合,与 List
集合平级。
该集合中元素没有先后放入次序,且不允许重复。
该集合的主要实现类是:HashSet
类 和 TreeSet
类以及 LinkedHashSet
类。
其中 HashSet
类的底层是采用哈希表进行数据管理的。
其中 TreeSet
类的底层是采用红黑树进行数据管理的。
其中 LinkedHashSet
类与 HashSet
类的不同之处在于内部维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。
常用的方法
参考 Collection
集合中的方法
元素放入 HashSet
集合的原理
使用元素调用 hashCode
方法获取对应的哈希码值,再由某种哈希算法计算出该元素在数组中的索引位置。
若该位置没有元素,则将该元素直接放入即可。
若该位置有元素,则使用新元素与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入。
若新元素与已有元素的哈希值相同,则使用新元素调用 equals
方法与已有元素依次比较。
若相等则添加元素失败,否则将元素直接放入即可。
重写 equals
方法后要重写 hashCode
方法的原因: 当两个元素调用 equals
方法相等时证明这两个元素相同,重写 hashCode
方法后保证这两个元素得到的哈希码值相同,由同一个哈希算法生成的索引位置相同,此时只需要与该索引位置已有元素比较即可,从而提高效率并避免重复元素的出现。
TreeSet
集合的概念
使用元素的自然排序规则进行比较并排序,让元素类型实现 java.lang.Comparable
接口;
public class Student implements Comparable{
@Override
public int compareTo(Student o) {
int ia = this.getName().compareTo(o.getName());
return 0 != ia? ia : this.getAge() - o.getAge();
}
}
使用比较器规则进行比较并排序,构造TreeSet集合时传入 java.util.Comparator
接口;
// 匿名内部类: 接口/父类类型 引用变量名 = new 接口/父类类型() { 方法的重写 };
Comparatorcomparator = new Comparator () {
@Override
// o1 表示新增加的对象,o2 表示集合中已有的对象
public int compare(Student o1, Student o2) {
// 表示按照年龄比较
return o1.getAge() - o2.getAge();
}
};
// 从 Java 8 开始支持Lambda表达式: (参数列表) -> { 方法体 }
Comparatorcomparator = (Student o1, Student o2) -> { return o1.getAge() - o2.getAge(); };
Sets2 = new TreeSet<>(comparator);
左子树中的任意节点元素都小于根节点元素值;
右子树中的任意节点元素都大于根节点元素值;
左子树和右子树的内部也遵守上述规则;
二叉树主要指每个节点最多只有两个子节点的树形结构。
满足以下 3 个特征的二叉树叫做有序二叉树。
由于 TreeSet
集合的底层采用红黑树进行数据的管理,当有新元素插入到 TreeSet
集合时,需要使用新元素与集合中已有的元素依次比较来确定新元素的合理位置。
比较元素大小的规则有两种方式:
自然排序的规则比较单一,而比较器的规则比较多元化,而且比较器优先于自然排序。
Map 集合
基本概念
java.util.Map
集合中存取元素的基本单位是:单对元素,其中类型参数如下: K
- 此映射所维护的键 (Key
) 的类型,相当于目录。 V
- 映射值 (Value
) 的类型,相当于内容。
该集合中 key
是不允许重复的,而且一个 key
只能对应一个 value
。
该集合的主要实现类有:HashMap
类、TreeMap
类、LinkedHashMap
类、Hashtable
类、Properties
类。
其中 HashMap
类的底层是采用哈希表进行数据管理的。
其中 TreeMap
类的底层是采用红黑树进行数据管理的。
其中 LinkedHashMap
类与 HashMap
类的不同之处在于内部维护了一个双向链表,链表中记录了元素的迭代顺序,也就是元素插入集合中的先后顺序,因此便于迭代。
其中 Hashtable
类是古老的 Map
实现类,与 HashMap
类相比属于线程安全的类,且不允许 null
作为 key
或者 value
的数值。
其中 Properties
类是 Hashtable
类的子类,该对象用于处理属性文件,key
和 value
都是 String
类型的。
Map
集合是面向查询优化的数据结构, 在大数据量情况下有着优良的查询性能。
经常用于根据 key
检索 value
的业务场景。
常用的方法
方法声明 | 功能介绍 |
---|---|
V put(K key, V value) |
将 Key-Value 对存入 Map ,若集合中已经包含该 Key ,则替换该 Key 所对应的 Value ,返回值为该 Key 原来所对应的 Value ,若没有则返回 null |
V get(Object key) |
返回与参数 Key 所对应的 Value 对象,如果不存在则返回 null |
boolean containsKey(Object key); |
判断集合中是否包含指定的 Key |
boolean containsValue (Object value); |
判断集合中是否包含指定的 Value |
V remove(Object key) |
根据参数指定的 key 进行删除 |
Set |
返回此映射中包含的键的 Set 视图 |
Collection |
返回此映射中包含的值的 Set 视图 |
Set |
返回此映射中包含的映射的 Set 视图 |
元素放入 HashMap
集合的原理
使用元素的 key
调用 hashCode
方法获取对应的哈希码值,再由某种哈希算法计算在数组中的索引位置。
若该位置没有元素,则将该键值对直接放入即可。
若该位置有元素,则使用 key
与已有元素依次比较哈希值,若哈希值不相同,则将该元素直接放入。
若 key
与已有元素的哈希值相同,则使用 key
调用 equals
方法与已有元素依次比较。
若相等则将对应的 value
修改,否则将键值对直接放入即可。
相关的常量
DEFAULT_INITIAL_CAPACITY
: HashMap
的默认容量是 16
。
DEFAULT_LOAD_FACTOR
:HashMap
的默认加载因子是 0.75
。
threshold
:扩容的临界值,该数值为:容量 * 填充因子
,也就是 12
。
TREEIFY_THRESHOLD
:若 Bucket
中链表长度大于该默认值则转化为红黑树存储,该数值是 8
。
MIN_TREEIFY_CAPACITY
:桶中的 Node
被树化时最小的 hash
表容量,该数值是 64
。
Collections 类
基本概念
java.util.Collections
类主要提供了对集合操作或者返回集合的静态方法。
常用的方法
方法声明 | 功能介绍 |
---|---|
static |
根据元素的自然顺序返回给定集合的最大元素 |
static T max(Collection extends T> coll, Comparator super T> comp) |
根据指定比较器引发的顺序返回给定集合的最大元素 |
static |
根据元素的自然顺序返回给定集合的最小元素 |
static T min(Collection extends T> coll, Comparator super T> comp) |
根据指定比较器引发的顺序返回给定集合的最小元素 |
static void copy(List super T> dest, List extends T> src) |
将一个列表中的所有元素复制到另一个列表中 |
方法声明 | 功能介绍 |
---|---|
static void reverse(List> list) |
反转指定列表中元素的顺序 |
static void shuffle(List> list) |
使用默认的随机源随机置换指定的列表 |
static |
根据其元素的自然顺序将指定列表按升序排序 |
static void sort(List list, Comparator super T> c) |
根据指定比较器指定的顺序对指定列表进行排序 |
static void swap(List> list, int i, int j) |
交换指定列表中指定位置的元素 |
常见异常
ConcurrentModificationException
并发修改异常
NumberFormatException
数字格式异常
IllegalArugumentException
非法参数异常
ClassCastException
类型转换异常
NullPointException
空指针异常
ArithmeticException
算术异常
ArrayIndexOutOfBoundsException
数组下标越界异常