String 類的概述
? String類: 代表 字符串揭糕。Java 程序中的所有字符串字面值(如 "abc" )都作為此類的實(shí)例實(shí)現(xiàn)绢涡。
? String是一個(gè)final類殖告,代表不可變的字符序列村生。
? 字符串是常量冰木,用雙引號(hào)引起來表示沿量。它們的值在創(chuàng)建之后不能更改浪慌。
? String對(duì)象的字符內(nèi)容是存儲(chǔ)在一個(gè)字符數(shù)組value[]中的。
理解 String 的不可變性
查看JDK的String源碼可以發(fā)現(xiàn)
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
public String() {
this.value = "".value;
}
}
String底層是使用 char 數(shù)組實(shí)現(xiàn)的 而且 value 的數(shù)組修飾符為 final 所以String是不可變的
String是不可被繼承的 public final class String
String是支持序列化的 實(shí)現(xiàn)了接口 java.io.Serializable
String支持比較大小 Comparable<String>
String 不同實(shí)例化方式的對(duì)比
String s1 = "abc";// 字面量的定義方式
String s2 = "abc";
s1 = "hello";
String 對(duì)象的 創(chuàng)建
String str = "hello";
// 本質(zhì)上this.value = new char[0];
String s1 = new String();
//this.value = original.value;
String s2 = new String(String original);
//this.value = Arrays.copyOf(value, value.length);
String s3 = new String(char[] a);
String s4 = new String(char[] a,int startIndex,int count);
String str1 = “abc”; 與String str2 = new String(“abc”);的區(qū)別朴则?
? 字符串常量存儲(chǔ)在字符串常量池权纤,目的是共享
? 字符串非常量對(duì)象存儲(chǔ)在堆中。
String是怎么存儲(chǔ)的
String s1 = "javaEE";
String s2 = "javaEE";
String s3 = new String("javaEE");
String s4 = new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
結(jié)論:
? 常量與常量的拼接結(jié)果在常量池。且常量池中不會(huì)存在相同內(nèi)容的常量汹想。
? 只要其中有一個(gè)是變量外邓,結(jié)果就在堆中
? 如果拼接的結(jié)果調(diào)用intern()方法,返回值就在常量池中
String 不同拼接操作的對(duì)比
? String s1 = "a";
說明:在字符串常量池中創(chuàng)建了一個(gè)字面量為"a"的字符串古掏。
? s1 = s1 + "b";
說明:實(shí)際上原來的“a”字符串對(duì)象已經(jīng)丟棄了坐榆,現(xiàn)在在堆空間中產(chǎn)生了一個(gè)字符串s1+"b"(也就是"ab")。如果多次執(zhí)行這些改變串內(nèi)容的操作冗茸,會(huì)導(dǎo)致大量副本字符串對(duì)象存留在內(nèi)存中席镀,降低效率。如果這樣的操作放到循環(huán)中夏漱,會(huì)極大影響程序的性能豪诲。
? String s2 = "ab";
說明:直接在字符串常量池中創(chuàng)建一個(gè)字面量為"ab"的字符串。
? String s3 = "a" + "b";
說明:s3指向字符串常量池中已經(jīng)創(chuàng)建的"ab"的字符串挂绰。
String s4 = s1.intern();
說明:堆空間的s1對(duì)象在調(diào)用intern()之后屎篱,會(huì)將常量池中已經(jīng)存在的"ab"符串賦值給s4。
String 的常用方法
? int length() :返回字符串的長(zhǎng)度: return value.length
? char charAt(int index): 返回某索引處的字符return value[index]
? boolean isEmpty() :判斷是否是空字符串:return value.length == 0
? String toLowerCase() :使用默認(rèn)語言環(huán)境葵蒂,將 String 中的所有字符轉(zhuǎn)換為小寫
? String toUpperCase() :使用默認(rèn)語言環(huán)境交播,將 String 中的所有字符轉(zhuǎn)換為大寫
? String trim(): 返回字符串的副本,忽略前導(dǎo)空白和尾部空白
? boolean equals(Object obj): 比較字符串的內(nèi)容是否相同
? boolean equalsIgnoreCase(String anotherString) :與equals方法類似践付,忽略大小寫
? String concat(String str) :將指定字符串連接到此字符串的結(jié)尾秦士。 等價(jià)于用“+”
? int compareTo(String anotherString) :比較兩個(gè)字符串的大小
? String substring(int beginIndex) :返回一個(gè)新的字符串,它是此字符串的從beginIndex開始截取到最后的一個(gè)子字符串永高。
? String substring(int beginIndex, int endIndex) :返回一個(gè)新字符串隧土,它是此字符串從beginIndex開始截取到endIndex(不包含)的一個(gè)子字符串。
? boolean endsWith(String suffix) :測(cè)試此字符串是否以指定的后綴結(jié)束
? boolean startsWith(String prefix) :測(cè)試此字符串是否以指定的前綴開始
? boolean startsWith(String prefix, int toffset) :測(cè)試此字符串從指定索引開始的子字符串是否以指定前綴開始
? boolean contains(CharSequence s) :當(dāng)且僅當(dāng)此字符串包含指定的 char 值序列時(shí)命爬,返回 true
? int indexOf(String str): 返回指定子字符串在此字符串中第一次出現(xiàn)處的索引
? int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引曹傀,從指定的索引開始
? int lastIndexOf(String str):返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引
? int lastIndexOf(String str, int fromIndex): 返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引,從指定的索引開始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
? String replace(char oldChar, char newChar):返回一個(gè)新的字符串饲宛,它是通過用 newChar 替換此字符串中出現(xiàn)的所有 oldChar 得到的皆愉。
? String replace(CharSequence target, CharSequence replacement): 使用指定的字面值替換序列替換此字符串所有匹配字面值目標(biāo)序列的子字符串。
? String replaceAll(String regex, String replacement) : 使 用 給 定 的
replacement 替換此字符串所有匹配給定的正則表達(dá)式的子字符串艇抠。
? String replaceFirst(String regex, String replacement) : 使 用 給 定 的
replacement 替換此字符串匹配給定的正則表達(dá)式的第一個(gè)子字符串幕庐。
? boolean matches(String regex) :告知此字符串是否匹配給定的正則表達(dá)式。
? String[] split(String regex):根據(jù)給定正則表達(dá)式的匹配拆分此字符串练链。
? String[] split(String regex, int limit):根據(jù)匹配給定的正則表達(dá)式來拆分此
字符串翔脱,最多不超過limit個(gè)奴拦,如果超過了媒鼓,剩下的全部都放到最后一個(gè)元素中。
回顧 String 與基本數(shù)據(jù)類型包裝類的轉(zhuǎn)換
字符串 -> 基本數(shù)據(jù)類型、包裝類
?Integer包裝類的public static int parseInt(String s):可以將由“數(shù)字”字
符組成的字符串轉(zhuǎn)換為整型绿鸣。
?類似地,使用java.lang包中的Byte疚沐、Short、Long潮模、Float亮蛔、Double類調(diào)相應(yīng)
的類方法可以將由“數(shù)字”字符組成的字符串,轉(zhuǎn)化為相應(yīng)的基本數(shù)據(jù)類型擎厢。
? 基本 數(shù)據(jù)類型究流、包裝類 ->字符串
?調(diào)用String類的public String valueOf(int n)可將int型轉(zhuǎn)換為字符串
?相應(yīng)的valueOf(byte b)、valueOf(long l)动遭、valueOf(float f)芬探、valueOf(double
d)、valueOf(boolean b)可由參數(shù)的相應(yīng)類型到字符串的轉(zhuǎn)換
String 與 char[]之間的轉(zhuǎn)換
? 字符數(shù)組 ->字符串
?String 類的構(gòu)造器:String(char[]) 和 和 String(char[] 厘惦,int offset 偷仿,int
length) 分別用字符數(shù)組中的全部字符和部分字符創(chuàng)建字符串對(duì)象。
? 字符串->字符 數(shù)組
?public char[] toCharArray():將字符串中的全部字符存放在一個(gè)字符數(shù)組中的方法宵蕉。
?public void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin):提供了將指定索引范圍內(nèi)的字符串存放到數(shù)組中的方法酝静。
String 與 byte[]之間的轉(zhuǎn)換
? 字節(jié)數(shù)組 -> 字符串
?String(byte[]) :通過使用平臺(tái)的默認(rèn)字符集解碼指定的 byte 數(shù)組,構(gòu)
造一個(gè)新的 String羡玛。
?String(byte[] 别智,int offset ,int length) :用指定的字節(jié)數(shù)組的一部分稼稿,
即從數(shù)組起始位置offset開始取length個(gè)字節(jié)構(gòu)造一個(gè)字符串對(duì)象亿遂。
? 字符串 -> 字節(jié)數(shù)組
?public byte[] getBytes() :使用平臺(tái)的默認(rèn)字符集將此 String 編碼為
byte 序列,并將結(jié)果存儲(chǔ)到一個(gè)新的 byte 數(shù)組中渺杉。
?public byte[] getBytes(String charsetName) : 使用指定的字符集將
此 String 編碼到 byte 序列蛇数,并將結(jié)果存儲(chǔ)到新的 byte 數(shù)組。
解決一個(gè)拼接問題
1,常量與常量的拼接結(jié)果是在常量池.而且常量池中不會(huì)有相同內(nèi)容的常量
2.只要其中一個(gè)是變量,那結(jié)果就是在堆中
3.如果拼接的結(jié)果調(diào)用intern()方法,返回值就在常量池中
4.使用 final 修飾的String是常量
面試中 String 算法考查的說明
- 模擬一個(gè) 個(gè)trim 方法是越,去除字符串兩端的空格 耳舅。
- 將一個(gè)字符串進(jìn)行反轉(zhuǎn)。將字符串中指定部分進(jìn)行 反轉(zhuǎn)如“abcdefg”反轉(zhuǎn)為”abfedcg”
- 獲取一個(gè)字符串在另一個(gè)字符串中出現(xiàn)的次數(shù)倚评。 比如:獲取“ ab”在“abkkcadkabkebfkabkskab” 中 出現(xiàn)的次數(shù)
- 獲取兩個(gè)字符串中最大相同子串浦徊。比如:
str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"
提示:將短的那個(gè)串進(jìn)行長(zhǎng)度依次遞減的子串與較長(zhǎng)的串比較。 - 對(duì)字符串中字符進(jìn)行自然順序排序 天梧。
提示:
1)字符串變成字符數(shù)組盔性。
2)對(duì)數(shù)組排序,選擇呢岗,冒泡冕香,Arrays.sort();
3)將排序后的數(shù)組變成字符串蛹尝。
StringBuffer 和 StringBuilder 的介紹
java.lang.StringBuffer代表 可變的字符 序列,JDK1.0中聲明悉尾,可以對(duì)字符
串內(nèi)容進(jìn)行增刪突那,此時(shí)不會(huì)產(chǎn)生新的對(duì)象。
? 很多方法與String相同构眯。
? 作為參數(shù)傳遞時(shí)愕难,方法內(nèi)部可以改變值
StringBuffer 的源碼分析
StringBuffer 類不同于String ,其對(duì)象必須使用構(gòu)造器生成惫霸。有 三 個(gè) 構(gòu)造 器 :
?StringBuffer() :初始為 容量為16 的字符串緩沖區(qū)
?StringBuffer(int size) :構(gòu)造 指定容量的字符串緩沖區(qū)
?StringBuffer(String str) :將內(nèi)容初始化為指定值
StringBuffer append(xxx):提供了很多的append()方法猫缭,用于進(jìn)行字符串拼接
StringBuffer delete(int start,int end):刪除指定位置的內(nèi)容
StringBuffer replace(int start, int end, String str):把[start,end)位置替換為str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把當(dāng)前字符序列逆轉(zhuǎn)
public int indexOf(String str)
public String substring(int start,int end)
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/**
* @since 1.5
*/
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
@Override
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
/**
* @since 1.5
*/
@Override
public synchronized int codePointAt(int index) {
return super.codePointAt(index);
}
/**
* @since 1.5
*/
@Override
public synchronized int codePointBefore(int index) {
return super.codePointBefore(index);
}
/**
* @since 1.5
*/
@Override
public synchronized int codePointCount(int beginIndex, int endIndex) {
return super.codePointCount(beginIndex, endIndex);
}
/**
* @since 1.5
*/
@Override
public synchronized int offsetByCodePoints(int index, int codePointOffset) {
return super.offsetByCodePoints(index, codePointOffset);
}
}
StringBuffer是線程安全的,因?yàn)樗姆椒ǘ际鞘褂?synchronized 修飾
StringBuffer 中的常用方法
StringBuilder 的方法和StringBuffer 基本一致
源碼
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder append(CharSequence s, int start, int end) {
super.append(s, start, end);
return this;
}
@Override
public StringBuilder append(char[] str) {
super.append(str);
return this;
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder append(char[] str, int offset, int len) {
super.append(str, offset, len);
return this;
}
@Override
public StringBuilder append(boolean b) {
super.append(b);
return this;
}
@Override
public StringBuilder append(char c) {
super.append(c);
return this;
}
@Override
public StringBuilder append(int i) {
super.append(i);
return this;
}
@Override
public StringBuilder append(long lng) {
super.append(lng);
return this;
}
@Override
public StringBuilder append(float f) {
super.append(f);
return this;
}
@Override
public StringBuilder append(double d) {
super.append(d);
return this;
}
/**
* @since 1.5
*/
@Override
public StringBuilder appendCodePoint(int codePoint) {
super.appendCodePoint(codePoint);
return this;
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder delete(int start, int end) {
super.delete(start, end);
return this;
}
}
所有的方法請(qǐng)查看API文檔或是源碼
這里的方法都沒有使用 synchronized 修飾
String、StringBuffer壹店、StringBuilder 效率對(duì)比
速度 排列
StringBuilder > StringBuffer > String
線程安全排列
String = StringBuffer > StringBuilder
StringBuilder 和 和 StringBuffer 非常類似饵骨,均代表可變的字符序列 , 而且
提供相關(guān)功能的方法 也 一樣
? 面試題:對(duì)比String 茫打、StringBuffer 居触、StringBuilder
?String(JDK1.0):不可變字符序列
?StringBuffer(JDK1.0):可變字符序列、效率低老赤、線程安全
?StringBuilder(JDK 5.0):可變字符序列轮洋、效率高、線程不安全
注意:作為參數(shù)傳遞的話抬旺,方法內(nèi)部String不會(huì)改變其值弊予,StringBuffer和StringBuilder 會(huì)改變其值。
System 類中獲取時(shí)間戳的方法
JDK8之前的時(shí)間的API
- java.lang.System類
System類提供的public static long currentTimeMillis()用來返回當(dāng)前時(shí)
間與1970年1月1日0時(shí)0分0秒之間以毫秒為單位的時(shí)間差开财。
? 此方法適于計(jì)算時(shí)間差汉柒。
?計(jì)算世界時(shí)間的主要標(biāo)準(zhǔn)有:
?UTC(Coordinated Universal Time)
?GMT(Greenwich Mean Time)
?CST(Central Standard Time)
public class TestDate {
public static void main(String[] args) {
//System方法 在1970年1月1日UTC之間的當(dāng)前時(shí)間和午夜之間的差異,以毫秒為單位责鳍。
Long time = System.currentTimeMillis();
System.out.println(time);
//1580644515959 打印結(jié)果
}
}
Java 中兩個(gè) Date 類的使用
java.util.Date類
表示特定的瞬間碾褂,精確到毫秒
? 構(gòu)造 器 :
? Date():使用無參構(gòu)造器創(chuàng)建的對(duì)象可以獲取本地當(dāng)前時(shí)間。
? Date(long date)
? 常用方法
? getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以來此 Date 對(duì)象
表示的毫秒數(shù)历葛。
? toString():把此 Date 對(duì)象轉(zhuǎn)換為以下形式的 String: dow mon dd
hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue,
Wed, Thu, Fri, Sat)正塌,zzz是時(shí)間標(biāo)準(zhǔn)。
? 其它很多方法都過時(shí)了恤溶。
public class TestDate {
public static void main(String[] args) {
//System方法 在1970年1月1日UTC之間的當(dāng)前時(shí)間和午夜之間的差異乓诽,以毫秒為單位。
Long time = System.currentTimeMillis();
System.out.println(time);
//1580644515959 打印結(jié)果
Date datetime = new Date();
//Sun Feb 02 20:10:06 CST 2020 打印
System.out.println(datetime);
//toString() 顯示當(dāng)前的年月日時(shí)分秒
//getTime().獲取當(dāng)前Date對(duì)象對(duì)應(yīng)的毫秒數(shù)
System.out.println(datetime.getTime());
//1580645406405
}
}
java.sql.Date 對(duì)應(yīng)數(shù)據(jù)庫的時(shí)間變量
IDEA 中 Debug 調(diào)試
public class TestStringBufferAndStringBuilder {
public static void main(String[] args) {
String str = null;
StringBuilder sb = new StringBuilder();
sb.append(str);
System.out.println(sb.length());
System.out.println(sb);
StringBuilder sb1 = new StringBuilder(str);
System.out.println(sb1);
}
}
打印結(jié)果
4
null
Exception in thread "main" java.lang.NullPointerException
at java.lang.StringBuilder.<init>(StringBuilder.java:112)
at cn.icanci.teststring.TestStringBufferAndStringBuilder.main(TestStringBufferAndStringBuilder.java:18)
SimpleDateFormat 的使用
java.text.SimpleDateFormat類
Date類的API不易于國際化咒程,大部分被廢棄了鸠天,java.text.SimpleDateFormat
類是一個(gè)不與語言環(huán)境有關(guān)的方式來格式化和解析日期的具體類。
? 它允許進(jìn)行 格式化:日期 ? 文本帐姻、 解析:文本 ? 日期
? 格式化:
? SimpleDateFormat() :默認(rèn)的模式和語言環(huán)境創(chuàng)建對(duì)象
? public SimpleDateFormat(String pattern) :該構(gòu)造方法可以用參數(shù)pattern
指定的格式創(chuàng)建一個(gè)對(duì)象稠集,該對(duì)象調(diào)用:
? public String format(Date date) :方法格式化時(shí)間對(duì)象date
? 解析:
? public Date parse(String source):從給定字符串的開始解析文本奶段,以生成一個(gè)日期。
public class TestSimpleDateFormat {
public static void main(String[] args) throws Exception {
/**
* SimpleDateFormat 對(duì)Date的格式化和解析
* 格式化:日期-->>字符串
* 解析"字符串 -->> 日期對(duì)象
*/
//使用默認(rèn)的構(gòu)造器哦
SimpleDateFormat sdf = new SimpleDateFormat();
Date date = new Date();
String format = sdf.format(date);
System.out.println(format);
String str = "20-2-2 下午8:32";
Date date2 = sdf.parse(str);
System.out.println(date2);
//使用構(gòu)造器
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format1 = sdf1.format(date);
System.out.println(format1);
}
}
Calendar 日歷類的使用
java.util.Calendar( 日歷)類 類
? Calendar是一個(gè)抽象基類巍杈,主用用于完成日期字段之間相互操作的功能。
? 獲取Calendar實(shí)例的方法
? 使用Calendar.getInstance()方法
? 調(diào)用它的子類GregorianCalendar的構(gòu)造器扛伍。
? 一個(gè)Calendar的實(shí)例是系統(tǒng)時(shí)間的抽象表示筷畦,通過get(int field)方法來取得想
要的時(shí)間信息。比如YEAR刺洒、MONTH鳖宾、DAY_OF_WEEK、HOUR_OF_DAY 逆航、MINUTE鼎文、SECOND
? public void set(int field,int value)
? public void add(int field,int amount)
? public final Date getTime()
? public final void setTime(Date date)
? 注意:
? 獲取月份時(shí):一月是0,二月是1因俐,以此類推拇惋,12月是11
? 獲取星期時(shí):周日是1,周二是2 抹剩, 撑帖。。澳眷。胡嘿。周六是7
public class Test {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
// 從一個(gè) Calendar 對(duì)象中獲取 Date 對(duì)象
Date date = calendar.getTime();
// 使用給定的 Date 設(shè)置此 Calendar 的時(shí)間
date = new Date(1234234235235L);
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_MONTH, 8);
System.out.println("當(dāng)前時(shí)間日設(shè)置為8后,時(shí)間是:" + calendar.getTime());
calendar.add(Calendar.HOUR, 2);
System.out.println("當(dāng)前時(shí)間加2小時(shí)后,時(shí)間是:" + calendar.getTime());
calendar.add(Calendar.MONTH, -2);
System.out.println("當(dāng)前日期減2個(gè)月后,時(shí)間是:" + calendar.getTime());
}
}
JDK8 中日期時(shí)間 API 的介紹
新日期間 時(shí)間API 出現(xiàn)的背景
如果我們可以跟別人說:“我們?cè)?502643933071見面,別晚了钳踊!”那么就再簡(jiǎn)單不
過了衷敌。但是我們希望時(shí)間與晝夜和四季有關(guān),于是事情就變復(fù)雜了拓瞪。JDK 1.0中包含了
一個(gè)java.util.Date類缴罗,但是它的大多數(shù)方法已經(jīng)在JDK 1.1引入Calendar類之后被棄用
了。而Calendar并不比Date好多少祭埂。它們面臨的問題是:
可變性:像日期和時(shí)間這樣的類應(yīng)該是不可變的瞒爬。
偏移性:Date中的年份是從1900開始的,而月份都從0開始沟堡。
格式化:格式化只對(duì)Date有用侧但,Calendar則不行。
此外航罗,它們也不是線程安全的禀横;不能處理閏秒等。
總結(jié):對(duì)日期和時(shí)間的操作一直是Java程序員最痛苦的地方之一粥血。
新時(shí)間日期API
? 第三次引入的API是成功的柏锄,并且Java 8中引入的java.time API 已經(jīng)糾正了
過去的缺陷酿箭,將來很長(zhǎng)一段時(shí)間內(nèi)它都會(huì)為我們服務(wù)。
? Java 8 吸收了 Joda-Time 的精華趾娃,以一個(gè)新的開始為 Java 創(chuàng)建優(yōu)秀的 API缭嫡。
新的 java.time 中包含了所有關(guān)于本地日期(LocalDate)、本地時(shí)間
(LocalTime)抬闷、本地日期時(shí)間(LocalDateTime)妇蛀、時(shí)區(qū)(ZonedDateTime)
和持續(xù)時(shí)間(Duration)的類。歷史悠久的 Date 類新增了 toInstant() 方法笤成,
用于把 Date 轉(zhuǎn)換成新的表示形式评架。這些新增的本地化時(shí)間日期 API 大大簡(jiǎn)
化了日期時(shí)間和本地化的管理。
新時(shí)間日期API
java.time – 包含值對(duì)象的基礎(chǔ)包
java.time.chrono – 提供對(duì)不同的日歷系統(tǒng)的訪問
java.time.format – 格式化和解析時(shí)間和日期
java.time.temporal – 包括底層框架和擴(kuò)展特性
java.time.zone – 包含時(shí)區(qū)支持的類
說明:大多數(shù)開發(fā)者只會(huì)用到基礎(chǔ)包和format包炕泳,也可能會(huì)用到temporal包纵诞。因此,盡管有68個(gè)新的公開類型培遵,大多數(shù)開發(fā)者浙芙,大概將只會(huì)用到其中的三分之一。
LocalDate籽腕、LocalTime茁裙、LocalDateTime 的使用
LocalDate、LocalTime节仿、LocalDateTime 類是其中較重要的幾個(gè)類晤锥,它們的實(shí)例是不可變的對(duì)象,分別表示使用 ISO-8601日歷系統(tǒng)的日期廊宪、時(shí)間矾瘾、日期和時(shí)間。
它們提供了簡(jiǎn)單的本地日期或時(shí)間箭启,并不包含當(dāng)前的時(shí)間信息壕翩,也不包含與時(shí)區(qū)相關(guān)的信息。
?LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存儲(chǔ) 生日傅寡、紀(jì)念日等日期放妈。
?LocalTime表示一個(gè)時(shí)間,而不是日期荐操。
?LocalDateTime是用來表示日期和時(shí)間的芜抒,這是一個(gè)最常用的類之一。
注:ISO-8601日歷系統(tǒng)是國際標(biāo)準(zhǔn)化組織制定的現(xiàn)代公民的日期和時(shí)間的表示法托启,也就是公歷宅倒。
- LocalDate
- LocalTime
- LocalDateTime
public class Test {
public static void main(String[] args) {
// now() 獲取當(dāng)前時(shí)間
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
// of():設(shè)置指定的年月日時(shí)分秒沒有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2020,5,5,12,12,45);
System.out.println(localDateTime1);
// getXxx()
System.out.println(localDate.getDayOfMonth());
System.out.println(localDate.getMonthValue());
System.out.println(localDate.getEra());
System.out.println(localDate.getYear());
// 設(shè)置 with
LocalDate localDate1 = localDate.withDayOfMonth(16);
// 體現(xiàn)不可變
System.out.println(localDate1);
System.out.println(localDate);
LocalDateTime localDateTime2 = localDateTime.withHour(3);
System.out.println(localDateTime2);
System.out.println(localDateTime);
//加減
LocalDateTime localDateTime3 = localDateTime.plusDays(8);
System.out.println(localDateTime3);
}
}
打印
2020-02-02
22:13:58.551
2020-02-02T22:13:58.551
2020-05-05T12:12:45
2
2
CE
2020
2020-02-16
2020-02-02
2020-02-02T03:13:58.551
2020-02-02T22:13:58.551
2020-02-10T22:13:58.551
Instant 類的使用
瞬時(shí):Instant
? Instant:時(shí)間線上的一個(gè)瞬時(shí)點(diǎn)。 這可能被用來記錄應(yīng)用程序中的事件時(shí)間戳屯耸。
? 在處理時(shí)間和日期的時(shí)候拐迁,我們通常會(huì)想到年,月,日,時(shí),分,秒蹭劈。然而,這只是時(shí)間的一個(gè)模型线召,是面向人類的铺韧。第二種通用模型是面向機(jī)器的,或者說是連續(xù)的缓淹。在此模型中哈打,時(shí)間線中的一個(gè)點(diǎn)表示為一個(gè)很大的數(shù),這有利于計(jì)算機(jī)處理割卖。在UNIX中前酿,這個(gè)數(shù)從1970年開始患雏,以秒為的單位鹏溯;同樣的,在Java中淹仑,也是從1970年開始丙挽,但以毫秒為單位。
? java.time包通過值類型Instant提供機(jī)器視圖匀借,不提供處理人類意義上的時(shí)間單位颜阐。Instant表示時(shí)間線上的一點(diǎn),而不需要任何上下文信息吓肋,例如凳怨,時(shí)區(qū)。
概念上講是鬼,它只是簡(jiǎn)單的表示自1970年1月1日0時(shí)0分0秒(UTC)開始的秒
數(shù)肤舞。因?yàn)閖ava.time包是基于納秒計(jì)算的,所以Instant的精度可以達(dá)到納秒級(jí)均蜜。
? (1 ns = 10 -9 s) 1秒 = 1000毫秒 =106微秒=109納秒
public class Test2 {
public static void main(String[] args) {
Instant instant = Instant.now();
// 本初子午線2020-02-02T14:16:56.802Z
System.out.println(instant);
OffsetDateTime offset = instant.atOffset(ZoneOffset.ofHours(8));
//2020-02-02T22:18:31.086+08:00
System.out.println(offset);
//1580653156469 獲取毫秒數(shù)
Long time = instant.toEpochMilli();
System.out.println(time);
Instant instant2 = Instant.ofEpochMilli(1580653156469L);
System.out.println(instant2);
}
}
打印結(jié)果
2020-02-02T14:20:46.299Z
2020-02-02T22:20:46.299+08:00
1580653246299
2020-02-02T14:19:16.469Z
DateTimeFormatter 的使用
格式化與解析日期 或 時(shí)間
java.time.format.DateTimeFormatter 類:該類提供了三種格式化方法:
? 預(yù)定義的標(biāo)準(zhǔn)格式李剖。如:
ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
? 本地化相關(guān)的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
? 自定義的格式囤耳。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
public class Test3 {
public static void main(String[] args) {
//方式1
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化時(shí)間
LocalDateTime localDateTime = LocalDateTime.now();
String time = formatter.format(localDateTime);
System.out.println(localDateTime);
System.out.println(time);
//解析
TemporalAccessor temporalAccessor = formatter.parse("2020-02-02T22:24:59.681");
System.out.println(temporalAccessor);
//方式2 本地格式化的方式
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG);
//格式化
String str2 = formatter1.format(localDateTime);
//下午10時(shí)30分21秒
System.out.println(str2);
//方式3 自定義的方式
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String time1 = dateFormatter.format(LocalDateTime.now());
System.out.println(time1);
}
}
打印
2020-02-02T22:33:20.737
2020-02-02T22:33:20.737
{},ISO resolved to 2020-02-02T22:24:59.681
下午10時(shí)33分20秒
2020-02-02 22:33:20
其它日期時(shí)間相關(guān) API 的使用
? ZoneId :該類中包含了所有的時(shí)區(qū)信息篙顺,一個(gè)時(shí)區(qū)的ID,如 Europe/Paris
? ZonedDateTime :一個(gè)在ISO-8601日歷系統(tǒng)時(shí)區(qū)的日期時(shí)間充择,如 2007-12-03T10:15:30+01:00 Europe/Paris德玫。
? 其中每個(gè)時(shí)區(qū)都對(duì)應(yīng)著ID,地區(qū)ID都為“{區(qū)域}/{城市}”的格式椎麦,例如:
Asia/Shanghai等
? Clock: :使用時(shí)區(qū)提供對(duì)當(dāng)前即時(shí)化焕、日期和時(shí)間的訪問的時(shí)鐘。
? 持續(xù)時(shí)間:Duration铃剔,用于計(jì)算兩個(gè)“時(shí)間”間隔
? 日期間隔:Period撒桨,用于計(jì)算兩個(gè)“日期”間隔
? TemporalAdjuster : 時(shí)間校正器查刻。有時(shí)我們可能需要獲取例如:將日期調(diào)整到“下一個(gè)工作日”等操作。
? TemporalAdjusters : 該類通過靜態(tài)方法
(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用
TemporalAdjuster 的實(shí)現(xiàn)凤类。
Java 比較器概述
在Java中經(jīng)常會(huì)涉及到對(duì)象數(shù)組的排序問題穗泵,那么就涉及到對(duì)象之間的比較問題。
? Java實(shí)現(xiàn)對(duì)象排序的方式有兩種:
? 自然排序:java.lang.Comparable
? 定制排序:java.util.Comparator
Comparable 自然排序舉例
? Comparable接口強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類的對(duì)象進(jìn)行整體排序谜疤。這種排序被稱
為類的自然排序佃延。
? 實(shí)現(xiàn) Comparable 的類必須實(shí)現(xiàn) compareTo(Object obj) 方法,兩個(gè)對(duì)象即
通過 compareTo(Object obj) 方法的返回值來比較大小夷磕。如果當(dāng)前對(duì)象this大
于形參對(duì)象obj履肃,則返回正整數(shù),如果當(dāng)前對(duì)象this小于形參對(duì)象obj坐桩,則返回
負(fù)整數(shù)尺棋,如果當(dāng)前對(duì)象this等于形參對(duì)象obj,則返回零绵跷。
? 實(shí)現(xiàn)Comparable接口的對(duì)象列表(和數(shù)組)可以通過 Collections.sort 或
Arrays.sort進(jìn)行自動(dòng)排序膘螟。實(shí)現(xiàn)此接口的對(duì)象可以用作有序映射中的鍵或有
序集合中的元素,無需指定比較器碾局。
? 對(duì)于類 C 的每一個(gè) e1 和 e2 來說荆残,當(dāng)且僅當(dāng) e1.compareTo(e2) == 0 與
e1.equals(e2) 具有相同的 boolean 值時(shí),類 C 的自然排序才叫做與 equals
一致净当。建議(雖然不是必需的)最好使自然排序與 equals 一致内斯。
自定義類實(shí)現(xiàn) Comparable 自然排序
Comparable 的典型 實(shí)現(xiàn):(默認(rèn)都是從小到大排列的)
?String:按照字符串中字符的Unicode值進(jìn)行比較
?Character:按照字符的Unicode值來進(jìn)行比較
?數(shù)值類型對(duì)應(yīng)的包裝類以及BigInteger、BigDecimal:按照它們對(duì)應(yīng)的數(shù)值
大小進(jìn)行比較
?Boolean:true 對(duì)應(yīng)的包裝類實(shí)例大于 false 對(duì)應(yīng)的包裝類實(shí)例
?Date像啼、Time等:后面的日期時(shí)間比前面的日期時(shí)間大
public class TestCompare {
/**
* Comparable 使用舉例
* 1.String Integer Long等包裝類實(shí)現(xiàn)了Comparable接口 重寫了 compareTo()方法
* 2.compareTo(obj)的規(guī)則
* 2.1 當(dāng)前對(duì)象this大于形參 obj 返回正整數(shù)
* 2.2 當(dāng)前對(duì)象this小于形參 obj 返回負(fù)整數(shù)
* 2.3 當(dāng)前對(duì)象this等于形參 obj 返回0
* 差值為距離值
*/
public static void main(String[] args) {
String[] str = new String[]{"AA","BB","SSS","DDASDA"};
Arrays.sort(str);
System.out.println(Arrays.toString(str));
}
}
public class Goods implements Comparable {
private String name;
private double price;
public Goods(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
/**
* 價(jià)格從高到低
*
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
if (o instanceof Goods) {
Goods goods = (Goods) o;
if (this.price > goods.price) {
return 1;
} else if (this.price < goods.price) {
return -1;
} else {
return this.compareTo(goods.name);
}
}
return 0;
}
}
public class Test4 {
public static void main(String[] args) {
Goods[] goods = new Goods[4];
goods[0] = new Goods("阿里",4561234);
goods[1] = new Goods("騰訊",4561234);
goods[2] = new Goods("百度",4561234);
goods[3] = new Goods("美團(tuán)",4564564);
Arrays.sort(goods);
System.out.println(Arrays.toString(goods));
}
}
使用 Comparator 實(shí)現(xiàn)定制排序
? 當(dāng)元素的類型沒有實(shí)現(xiàn)java.lang.Comparable 接口而又不方便修改代碼俘闯,
了 或者實(shí)現(xiàn)了java.lang.Comparable 接口的排序規(guī)則不適合當(dāng)前的操作,那
用 么可以考慮使用 Comparator 的對(duì)象來 排序埋合,強(qiáng)行對(duì)多個(gè)對(duì)象進(jìn)行整體排
序的比較备徐。
? 重寫compare(Object o1,Object o2)方法,比較o1和o2的大猩跛獭: 如果方法返示 回正整數(shù)蜜猾,則表示o1 大于o2 ;如果返回0 振诬,表示相等蹭睡;返回負(fù)整數(shù),表示o1 小于o2赶么。
? 可以將 Comparator 傳遞給 sort 方法(如 Collections.sort 或 Arrays.sort)肩豁,從而允許在排序順序上實(shí)現(xiàn)精確控制。
? 還可以使用 Comparator 來控制某些數(shù)據(jù)結(jié)構(gòu)(如有序 set或有序映射)的順序,或者為那些沒有自然順序的對(duì)象 collection 提供排序清钥。
public class Goods implements Comparable {
private String name;
private double price;
public Goods(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
/**
* 價(jià)格從高到低
*
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
if (o instanceof Goods) {
Goods goods = (Goods) o;
if (this.price > goods.price) {
return 1;
} else if (this.price < goods.price) {
return -1;
} else {
return this.compareTo(goods.name);
}
}
return 0;
}
}
public class Test5 {
/**
* 定制排序
* @param args
*/
public static void main(String[] args) {
Goods[] goods = new Goods[4];
goods[0] = new Goods("阿里",4561234);
goods[1] = new Goods("騰訊",4561234);
goods[2] = new Goods("百度",4561234);
goods[3] = new Goods("美團(tuán)",4564564);
Arrays.sort(goods, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
if (o1.getName().equals(o2.getName())){
return Double.compare(o1.getPrice(),o2.getPrice());
}else{
return o1.getName().compareTo(o2.getName());
}
}
});
System.out.println(Arrays.toString(goods));
}
}
System類
? System類代表系統(tǒng)琼锋,系統(tǒng)級(jí)的很多屬性和控制方法都放置在該類的內(nèi)部。
該類位于java.lang包祟昭。
? 由于該類的構(gòu)造器是private的缕坎,所以無法創(chuàng)建該類的對(duì)象,也就是無法實(shí)
例化該類篡悟。其內(nèi)部的成員變量和成員方法都是static的谜叹,所以也可以很方便
的進(jìn)行調(diào)用。
? 成員變量
? System類內(nèi)部包含in搬葬、out和err三個(gè)成員變量荷腊,分別代表標(biāo)準(zhǔn)輸入流
(鍵盤輸入),標(biāo)準(zhǔn)輸出流(顯示器)和標(biāo)準(zhǔn)錯(cuò)誤輸出流(顯示器)急凰。
? 成員方法
? native long currentTimeMillis(): :
該方法的作用是返回當(dāng)前的計(jì)算機(jī)時(shí)間女仰,時(shí)間的表達(dá)格式為當(dāng)前計(jì)算機(jī)時(shí)
間和GMT時(shí)間(格林威治時(shí)間)1970年1月1號(hào)0時(shí)0分0秒所差的毫秒數(shù)。
? void exit(int status): :
該方法的作用是退出程序香府。其中status的值為0代表正常退出董栽,非零代表
異常退出码倦。 使用該方法可以在圖形界面編程中實(shí)現(xiàn)程序的退出功能等企孩。
? void gc(): :
該方法的作用是請(qǐng)求系統(tǒng)進(jìn)行垃圾回收。至于系統(tǒng)是否立刻回收袁稽,則
取決于系統(tǒng)中垃圾回收算法的實(shí)現(xiàn)以及系統(tǒng)執(zhí)行時(shí)的情況勿璃。
? String getProperty(String key): :
該方法的作用是獲得系統(tǒng)中屬性名為key的屬性對(duì)應(yīng)的值。系統(tǒng)中常見
的屬性名以及屬性的作用如下表所示:
Math類
java.lang.Math 提供了一系列靜態(tài)方法用于 科學(xué) 計(jì)算推汽。其 方法的參數(shù)和返回
為 值類型一般為double 型补疑。
abs 絕對(duì)值
acos,asin,atan,cos,sin,tan 三角函數(shù)
sqrt 平方根
pow(double a,doble b) a 的b 次冪
log 自然對(duì)數(shù)
exp e 為底指數(shù)
max(double a,double b)
min(double a,double b)
random() 返回0.0 到1.0 的隨機(jī)數(shù)
long round(double a) double 型數(shù)據(jù)a 轉(zhuǎn)換為long 型(四舍五入)
toDegrees(double angrad) 弧度—> 角度
toRadians(double angdeg) 角度—>弧度
BigInteger與BigDecimal
? Integer類作為int的包裝類,能存儲(chǔ)的最大整型值為2 31 -1歹撒,Long類也是有限的莲组,
最大為2 63 -1。如果要表示再大的整數(shù)暖夭,不管是基本數(shù)據(jù)類型還是他們的包裝類
都無能為力锹杈,更不用說進(jìn)行運(yùn)算了。
? java.math包的BigInteger 可以表示不可變的任意精度的整數(shù)迈着。BigInteger 提供
所有 Java 的基本整數(shù)操作符的對(duì)應(yīng)物竭望,并提供 java.lang.Math 的所有相關(guān)方法。
另外裕菠,BigInteger 還提供以下運(yùn)算:模算術(shù)咬清、GCD 計(jì)算、質(zhì)數(shù)測(cè)試、素?cái)?shù)生成旧烧、
位操作以及一些其他操作影钉。
? 構(gòu)造器
? BigInteger(String val):根據(jù)字符串構(gòu)建BigInteger對(duì)象
常用 方法
? public BigInteger abs():返回此 BigInteger 的絕對(duì)值的 BigInteger。
? BigInteger add(BigInteger val) :返回其值為 (this + val) 的 BigInteger
? BigInteger subtract(BigInteger val) :返回其值為 (this - val) 的 BigInteger
? BigInteger multiply(BigInteger val) :返回其值為 (this * val) 的 BigInteger
? BigInteger divide(BigInteger val) :返回其值為 (this / val) 的 BigInteger掘剪。整數(shù)相除只保留整數(shù)部分斧拍。
? BigInteger remainder(BigInteger val) :返回其值為 (this % val) 的BigInteger。
? BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟(this % val) 的兩個(gè) BigInteger 的數(shù)組杖小。
? BigInteger pow(int exponent) :返回其值為 (this exponent ) BigInteger肆汹。
BigDecimal類
一般的Float類和Double類可以用來做科學(xué)計(jì)算或工程計(jì)算,但在 商業(yè)計(jì)算中予权,
到 要求數(shù)字精度比較高昂勉,故用到j(luò)ava.math.BigDecimal類 類 。
? BigDecimal類支持不可變的扫腺、任意精度的有符號(hào)十進(jìn)制定點(diǎn)數(shù)岗照。
? 構(gòu)造器
? public BigDecimal(double val)
? public BigDecimal(String val)
? 常用方法
? public BigDecimal add(BigDecimal augend)
? public BigDecimal subtract(BigDecimal subtrahend)
? public BigDecimal multiply(BigDecimal multiplicand)
? public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode