Java常用工具類匯總 附示例代碼
Java常用類


String類
- 概述
- String類:代表字符串。Java程序中的所有字符串字面值(如:”abc“)都作為子類的實例實現
- String是一個final類,代表不可變的字符序列
- 字符串是常量,用雙引號引起來表示。他們的值在創(chuàng)建之后不能更改
- String對象的字符內容是存儲在一個字符數組value[]中的
public final class String
implements java.io.Serializable,Comparable<String>,CharSequence{
/** The value is used for character storage*/
private final char value[]; //String 的底層就是放在char型數組當中(字符構成的串) //final:value是引用類型 其指向的地址不可以被修改
/*Cache the hash code for the string*/
private int hash; //Default to 0
}
/*
String:字符串:使用一對“”引起來表示
1. String聲明為final的,不可被繼承
2. String
實現了Serializable接口:表示字符串是可序列化的
(對象默認不可以通過網絡傳輸,但是如果是可序列化的,那么就可以通過網絡傳輸給對方 IO流部分知識)
實現了Comparable接口,表示String是可以比較大小的
3. String在內部定義了final的char型數組:final char value[] value用與存儲字符串數據
4. 通過字面量的方式(區(qū)別于new)給一個字符串賦值,此時的字符串值聲明在字符串常量池中
5. 字符串常量池中是不會存儲相同內容的字符串的
*/
- String不可變性
- 說明以及代碼
/*4. final:數組引用變量不能在指向別的數組,且數組對象內的元素也不能改變
即const int* const p; p是常量指針,且不能通過p對所指向的變量進行修改
體現
1)當對字符串重新賦值是,需要重寫指定內存區(qū)域賦值,不能使用原有的value進行賦值
2) 當對現有的字符串進行連接操作時,也需要重新制定內存區(qū)域賦值,不能使用原有的字符串*/
@Test
public void test(){
String s1 = "abc";//字面量的定義方式
String s2 = "abc";
System.out.println(s1==s2);//true
// s1="hello";
String s3 = "abc";
s3+="def";//并沒有改變“abc” 而是新造了一個
System.out.println(s3); //abcdef 并沒有改變“abc” 而是新造了一個
System.out.println(s2);//abc
System.out.println("******************");
String s4 = "abc";
String s5 = s4.replace('a','z');
System.out.println(s5);
System.out.println(s4);
System.out.println(s2);
}

//String 實例化的方式 // 方式一:通過字面量定義的方式 // 方式二:通過new+構造器的方式
@Test
public void test2(){
//通過字面量的方式 這個abc聲明在方法區(qū)的字符串常量池種
String s1 = "abc";
String s2 = "abc";
//通過new+構造器的方式:此時的s3,s4保存的地址值,是數據在堆空間中開辟空間以后堆空間中地址值
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1==s2); //true
System.out.println(s1==s3); //false
System.out.println(s3==s2); //false
System.out.println("********************");
Person p1 = new Person("shc");
Person p2 = new Person("shc");
System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name==p2.name);//true 因為在Person的對象中,生成String字符串的方式也是通過字面量 this.name="shc"
//如果在Peron的構造器中用this.name=new String("shc"); 的方式,那么就是false
}
面試題:
面試題:!!!???String s = new String("abc"); 方式創(chuàng)建對象,在內存中創(chuàng)建了幾個對象 兩個:一個是堆空間中new結構,另一個是char[]對應的常量池中的數據:"abc";





- 字符串拼接方式的對比
/*
1. 常量與與常量的拼接結果在常量池中,且常量池中不會存在相同內容的常量
2. 只要其中有一個是變量,結果就在堆中
3. 如果拼接的結果調用intern()方法,返回值就在常量池中
*/
@Test
public void test3(){
String s1 = "abc";
String s2 = "hhh";
String s3 = "abchhh"; //字面量
String s4 = "abc"+"hhh"; //兩個字面量的連接 還是字面量 在常量池中
String s5 = s1+"hhh";
String s6 = "abc" + s2;
String s7 = s1+s2;
System.out.println(s3==s4); //true
System.out.println(s3==s5); //false
System.out.println(s3==s6); //false
System.out.println(s3==s7); //false
System.out.println(s5==s6); //false
System.out.println(s5==s7); //false
System.out.println(s6==s7); //false
String s = s5.intern();
System.out.println(s==s3);//true
}
- String用方法
/** * int length():返回字符串的長度: return value.length * char charAt(int index): 返回某索引處的字符return value[index] * boolean isEmpty():判斷是否是空字符串:return value.length == 0 * String toLowerCase():使用默認語言環(huán)境,將 String 中的所有字符轉換為小寫 * String toUpperCase():使用默認語言環(huán)境,將 String 中的所有字符轉換為大寫 * String trim():返回字符串的副本,忽略前導空白和尾部空白 * boolean equals(Object obj):比較字符串的內容是否相同 * boolean equalsIgnoreCase(String anotherString):與equals方法類似,忽略大小寫 * String concat(String str):將指定字符串連接到此字符串的結尾。 等價于用“+” * int compareTo(String anotherString):比較兩個字符串的大小 * String substring(int beginIndex):返回一個新的字符串,它是此字符串的從 * beginIndex開始截取到最后的一個子字符串。 * String substring(int beginIndex, int endIndex) :返回一個新字符串,它是此字 * 符串從beginIndex開始截取到endIndex(不包含)的一個子字符串。 * * boolean endsWith(String suffix):測試此字符串是否以指定的后綴結束 * boolean startsWith(String prefix):測試此字符串是否以指定的前綴開始 * boolean startsWith(String prefix, int toffset):測試此字符串從指定索引開始的 * 子字符串是否以指定前綴開始 * * boolean contains(CharSequence s):當且僅當此字符串包含指定的 char 值序列時,返回 true * int indexOf(String str):返回指定子字符串在此字符串中第一次出現處的索引 * int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出 * 現處的索引,從指定的索引開始 * int lastIndexOf(String str):返回指定子字符串在此字符串中最右邊出現處的索引 * int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出現處的索引,從指定的索引開始反向搜索 * 注:indexOf和lastIndexOf方法如果未找到都是返回-1 * * String replace(char oldChar, char newChar):返回一個新的字符串,它是 * 通過用 newChar 替換此字符串中出現的所有 oldChar 得到的。 * String replace(CharSequence target, CharSequence replacement):使 * 用指定的字面值替換序列替換此字符串所有匹配字面值目標序列的子字符串。 * String replaceAll(String regex, String replacement) : 使 用 給 定 的 * replacement 替換此字符串所有匹配給定的正則表達式的子字符串。 * String replaceFirst(String regex, String replacement) : 使 用 給 定 的 * replacement 替換此字符串匹配給定的正則表達式的第一個子字符串。 * * boolean matches(String regex):告知此字符串是否匹配給定的正則表達式 * * String[] split(String regex):根據給定正則表達式的匹配拆分此字符串。 * String[] split(String regex, int limit):根據匹配給定的正則表達式來拆分此 * 字符串,最多不超過limit個,如果超過了,剩下的全部都放到最后一個元素中。 * @author shc * @create 2021-05-20 15:06 */
- String與其他結構的轉換
- 與基本數據類型,包裝類之間的轉換
/*
String與基本數據類型,包裝類之間的轉換
String --> 基本數據類型,包裝類 :調用基本數據類型的 parseXxx(str);
基本數據類型,包裝類 ---> String :調用String類重載的valueOf(xxx); 或者直接+""
*/
@Test
public void test(){
String str = "123";
// int num = (int) str; //必須是子父類的關系才可以強轉
int num = Integer.parseInt(str); //注意str中不能有數字 否則NumberFormatException
System.out.println(num);
String str1 = String.valueOf(num);
String str2 = num+"";
System.out.println(str1+" "+str2);
}
String與字符數組之間的轉換
/*
String與char[]之間的轉換
String -->char[] 調用String的toCharArray()
char[] -->String 調用String的構造器
*/
@Test
public void test2(){
String str1 = "abc123";
char[] charArray = str1.toCharArray();
for(int i=0;i<charArray.length;i++){
System.out.print(charArray[i]+" ");
}
char[] arr = new char[]{'h','e','l','l','o'};
String str = new String(arr);
System.out.println(str);
}
String與字節(jié)數組之間的轉換
/* String與byte[]之間的轉換 編碼:String --> byte[]:調用String的getBytes() 解碼:byte[] --> String 編碼:字符串 --> 字節(jié) (看得懂 --> 看不懂) 解碼:編碼的逆過程 字節(jié) --> 字符串 (看不懂的二進制 --> 看得懂) 說明:要求編碼時使用的字符集和解碼時使用的字符集必須一致 */
@Test
public void test3() throws UnsupportedEncodingException {
String str1 = "abc123中國";
byte[] bytes = str1.getBytes();//使用默認的字符集。進行轉換
System.out.println(Arrays.toString(bytes));
byte[] gbks = str1.getBytes("gbk");//使用gbk字符集進行編碼
System.out.println(str1);
System.out.println(Arrays.toString(gbks));
System.out.println("****************");
String str2 = new String(bytes);//使用默認字符集進行解碼
System.out.println(str2);
String gbks1 = new String(gbks);
System.out.println(gbks1);//亂碼
}
與StringBuilder,StringBuffer之間的轉換
String --> StringBuffer、StringBuilder:調用StringBuffer、StringBuilder構造器 StringBuffer、StringBuilder --> String: ①調用String構造器 ②StringBuffer、StringBuilder的toString()
/*
String、StringBuilder、StringBuffer三者異同?
String:不可變的字符序列 ,char型數組存儲
StringBuffer:可變的字符序列:線程安全,效率偏低,char型數組存儲
StringBuilder:可變的字符序列:jdk5.0新增 線程不安全,效率高,char型數組存儲
三者效率:StringBuilder > StringBuffer > String
源碼分析:
String str = new String(); //char[] value = new char[0];
String str1 = new String("abc);//char[] value = new char[]={'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];//底層創(chuàng)建了一個長度為16的字符串數組
sb1.append('a');//value[0]='a';
sb1.append('b');//value[1]='b';
StringBuffer sb2 = new String("abc"); //char[] value = new char["abc".length()+16];
QUESTION 1:sout(sb2.length()); //"abc".length;
2:擴容問題:如果要添加的數據底層數組撐不下了,就要擴容底層的數組
默認情況下,擴容為原來容量的2倍+2,同時將原有數組中的元素復制到新的數組中。
指導意義:開發(fā)中建議大家使用:StringBuffer(int capacity)或者(StringBuilder(int capacity) 盡量避免擴容,影響效率
*/
@Test
public void test(){
StringBuffer str1 = new StringBuffer("abc");
str1.setCharAt(0,'n');
System.out.println(str1);
}
JVM中字符常量池存放位置說明:
- jdk 1.6(jdk 6.0,java 6.0):字符串常量池儲存在方法區(qū)(永久區(qū))
- jdk 1.7:字符串常量池存儲在堆空間
- jdk 1.8:字符
StringBuilder,StringBuffer
public class StringBuilderBufferTest {
/*
String、StringBuilder、StringBuffer三者異同?
String:不可變的字符序列 ,char型數組存儲
StringBuffer:可變的字符序列:線程安全,效率偏低,char型數組存儲
StringBuilder:可變的字符序列:jdk5.0新增 線程不安全,效率高,char型數組存儲
三者效率:StringBuilder > StringBuffer > String
源碼分析:
String str = new String(); //char[] value = new char[0];
String str1 = new String("abc);//char[] value = new char[]={'a','b','c'};
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16];//底層創(chuàng)建了一個長度為16的字符串數組
sb1.append('a');//value[0]='a';
sb1.append('b');//value[1]='b';
StringBuffer sb2 = new String("abc"); //char[] value = new char["abc".length()+16];
QUESTION 1:sout(sb2.length()); //"abc".length;
2:擴容問題:如果要添加的數據底層數組撐不下了,就要擴容底層的數組
默認情況下,擴容為原來容量的2倍+2,同時將原有數組中的元素復制到新的數組中。
指導意義:開發(fā)中建議大家使用:StringBuffer(int capacity)或者(StringBuilder(int capacity) 盡量避免擴容,影響效率
*/
@Test
public void test(){
StringBuffer str1 = new StringBuffer("abc");
str1.setCharAt(0,'n');
System.out.println(str1);
}
}
/*
* StringBuffer類不同于String,其對象必須使用構造器生成。有三個構造器:
StringBuffer():初始容量為16的字符串緩沖區(qū)
StringBuffer(int size):構造指定容量的字符串緩沖區(qū)
StringBuffer(String str):將內容初始化為指定字符串內容
常用方法
StringBuffer append(xxx):提供了很多的append()方法,用于進行字符串拼接
StringBuffer delete(int start,int end):刪除指定位置的內容
StringBuffer replace(int start, int end, String str):把[start,end)位置替換為str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把當前字符序列逆轉
* 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)
*
* 總結
* 增 append(x)
* 刪 delete(int start,int end)
* 改 setCharAt(int n,char ch) / repalce(int start,int end,String str)
* 查 charAt(int n)
* 插 insert(int offset,xxx)
* 長度 length()
* 遍歷 for()+charAt() / toString()
*
*/


面試題







JDK8之前的時間API
獲取當前系統(tǒng)時間java.lang.System類中的currentTimeMillis()
long time = System.currentTimeMillis(); //返回時間為當前時間與1970年1月1日00:00之間以ms為單位的時間差,稱為時間戳 System.out.println(time); //1621602510493
java.util.Date與java.sql.Date
java.sql.Date extends java.util.Date
/*
2. java.util.Date類
① 兩個構造器的使用
>構造器一:Date()創(chuàng)建一個對應當前時間的Date對象
>構造器二:創(chuàng)建指定毫秒數(指定時間戳)的Date對象
② 兩個方法的使用
>toString():顯示當前的年、月、日、時、分、秒
>getTime();獲取當前Date對象的時間戳
③ java.sql.Date類 extends java.util.Date
>如何實例化
>如何將java.util.Date對象轉化為java.sql.Date對象
*/
@Test
public void test2(){
//構造器一:Date()創(chuàng)建一個對應當前時間的Date對象
Date date1 = new Date();
System.out.println(date1.toString());//Fri May 21 21:07:33 CST 2021
System.out.println(date1.getTime());//1621602495849
//構造器二:創(chuàng)建指定毫秒數的Date對象
Date date2 = new Date(1621602495849L);
System.out.println(date2.toString());//FriMay 21 21:08:15 CST 2021
//或者直接date2也一樣,因為sout就是會調用toString啊。
//這可不是把Date類對象轉化成String類對象了!?。。。。。?
System.out.println("*****************");
//創(chuàng)建java.sql.Date對象
java.sql.Date date3 = new java.sql.Date(323156136L);
System.out.println(date3);//1970-01-05
//如何將java.util.Date對象轉化為java.sql.Date對象
//情況1:(Java多態(tài))
Date date4 = new java.sql.Date(1235346456L);
java.sql.Date date5 = (java.sql.Date)date4;
//情況2:
Date date6 = new Date();
java.sql.Date date7 = new java.sql.Date(date6.getTime());
//而不能是java.sql.Date date7 = (java.sql.Date)date6;
}
java.text.SimpleDateFormat類
用處:SimpleDateFormat對日期Date類的 格式化和 解析(Date里還有很多方法被@Deprecated了)(JDK8建議用Calendar)
- (1)兩個操作
- 1.1: 格式化:日期(Date) --> 字符串(String)
- 1.2: 解析:格式化的逆過程:字符串(String) --> 日期(Date)
- (2)SimpleDateFormat的實例化:new+構造器.
- 基本操作
//1. 實例化SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat();
//2. 格式化:日期 (Date)--> 字符串(String)
Date date = new Date(); //Date()創(chuàng)建一個對應當前時間的Date對象
System.out.println(date);// Sat May 22 19:50:32 CST 2021
String format = sdf.format(date); // SimpleDateFormat對Date進行解析,獲得字符串:21-5-22 下午7:50
System.out.println(format); // 輸出解析后得到的字符串 21-5-22 下午7:50
//解析:格式化的逆過程。字符串(String) ---> 日期(Date)
String str = "21-5-22 下午7:49";
Date date1 = sdf.parse(str);//可能導致編譯異常原因:字符串格式不對
System.out.println(date1);//Sat May 22 19:49:00 CST 2021
(3)以下為開發(fā)中主要方式 --> 按照指定方式格式化和解析 :調用帶參構造器
//開發(fā)中通常不用默認構造器,而是用指定的構造器來確定格式化方式
//SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");
//年 yyyy -- 月 MM (大寫是為了和分鐘mm區(qū)分開) -- 天 dd -- 時 hh -- 分鐘 mm -- 秒 ss
//1. 實例化
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd ---- hh:mm:ss");
//2. 格式化
String format2 = sdf2.format(date);//以我們制定的yyyy-MM-dd ---- hh:mm:ss格式來進行轉化
System.out.println(format2);//2021-05-23 ---- 01:22:21
//3. 解析:
//要求字符串必須是符合SimpleDateFormat識別的格式(通過構造器參數體現),否則就會拋出異常
Date date2 = sdf2.parse("2021-05-23 ---- 01:22:21");
System.out.println(date2);//Sun May 23 01:22:21 CST 2021
Calendar類:日歷類,抽象類
/*
Calendar日歷類(抽象類)的使用
*/
@Test
public void testCalendar(){
//1.實例化
//方式一:創(chuàng)建其子類(GregorianCalendar)的對象
//方式二:調用其靜態(tài)方法getInstance();
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getClass());//class java.util.GregorianCalendar
//2.常用方法
//get()
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//23
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//143
//set()
//Calendar劣勢:可變性
calendar.set(Calendar.DAY_OF_MONTH,7);//void set() 把Calendar本身給改了
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//7
//add()
calendar.add(Calendar.DAY_OF_MONTH,-3);//4
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//getTime():日歷類 ---> Date
Date date = calendar.getTime();
System.out.println(date);//Tue May 04 13:45:07 CST 2021
System.out.println("****************");
//setTime():Date --> 日歷類
Date date1 = new Date();
calendar.setTime(date1);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//23
- JDK8中新的API
- 日期時間API的迭代
- 第一代:jdk 1.0 Date類
- 第二代:jdk 1.1 Calendar類,一定程度上替換Date類
- 第三代:jdk1.8提出了新的一套API(最終版)
- 前兩代存在的問題
- 可變性:像日期和時間這樣的類應該是不可變的。
- 偏移性:Date中的年份是從1900開始的,而月份都從0開始。
- 格式化:格式化只對Date有用,Calendar則不行。
- 此外,它們也不是線程安全的;不能處理閏秒等。

本地日期、本地時間、本地日期時間的使用:LocalDate、LocalTime、LocalDateTime
- 說明:
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存儲 生日、紀念日等日期。
- LocalTime表示一個時間,而不是日期。
- LocalDateTime是用來表示日期和時間的,這是一個最常用的類之一。
- 常用方法:

時間點:Instant
- 說明:
- Instant表示時間線上的一點,而不需要任何上下文信息,例如,時區(qū)。 概念上講,它只是簡單的表示自1970年1月1日0時0分0秒(UTC)開始的秒 數。
- 類似于java.util.Date類
- 常用方法

- 日期時間格式化類:DateTimeFormatter
說明
- 格式化、解析日期,時間
- 類似于SimpleDateFormat
常用方法
- 實例化方法
- 預定義的標準格式。如: ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
- 本地化相關的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
- 自定義的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
- 常用方法:

特別的,自定義格式,如:如:ofPattern(“yyyy-MM-dd hh:mm:ss”)*
//方式三:自定義的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//格式化
String str4 = formatter3.format(LocalDateTime.now());
System.out.println(str4);//2021-05-22 11:07:16
//解析:
TemporalAccessor accessor = formatter3.parse("2021-05-22 03:06:09");
System.out.println(accessor);
//{NanoOfSecond=0, MilliOfSecond=0, MinuteOfHour=6, SecondOfMinute=9, MicroOfSecond=0, HourOfAmPm=3},ISO resolved to 2021-05-22
}
其他常用類



package com.shc.java1;
import org.junit.Test;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
* 1. System
* 2. Math
* 3. BigInteger BigDecimal
* @author shc
* @create 2021-05-23 12:29
*/
public class OtherTest {
@Test
public void test1(){
String javaVersion = System.getProperty("java.version");
System.out.println("java的version:" + javaVersion);
String javaHome = System.getProperty("java.home");
System.out.println("java的home:" + javaHome);
String osName = System.getProperty("os.name");
System.out.println("os的name:" + osName);
String osVersion = System.getProperty("os.version");
System.out.println("os的version:" + osVersion);
String userName = System.getProperty("user.name");
System.out.println("user的name:" + userName);
String userHome = System.getProperty("user.home");
System.out.println("user的home:" + userHome);
String userDir = System.getProperty("user.dir");
System.out.println("user的dir:" + userDir);
}
@Test
public void test2(){
BigInteger bi = new BigInteger("12433241123");
BigDecimal bd = new BigDecimal("12435.351");
BigDecimal bd2 = new BigDecimal("10");
System.out.println(bi);
// System.out.println(bd.divide(bd2)); 魏沒有指明精度 如果除不盡的話會異常
System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));//四舍五入
System.out.println(bd.divide(bd2, 20, BigDecimal.ROUND_HALF_UP)); //scale:小數位位數 支持任意精度的小數位
}
}
Java比較器·
引入
* 說明:Java中的對象中,正常情況下,只能進行比較:== 或者 != 不能使用>或者<的 * 但是在開發(fā)場景中,我們需要對多個對象進行排序,言外之意,就是要比較對象的大小 * 如何實現? 使用兩個接口中的任何一個:Comparable 或 Compare任意一個
自然排序Comparable
說明
/*
Comparable接口使用舉例:自然排序
1. 像String、包裝類等實現了Comparable接口,重寫compareTo()方法,給出比較兩個對象大小的方式
2. 像String、包裝類重寫了compareTo方法以后,進行了從小到大的排列
3. 重寫compareTo()的規(guī)則
如果當前對象this大于形參對象obj,則返回正整數,
如果當前對象this小于形參對象obj,則返回負整數,
如果當前對象this等于形參對象obj,則返回零。
4. 對于自定義類來說,如果需要排序,我們可以自定義類實現Comparable接口,重寫compareTo方法,
在compareTo(obj)指明如何排序。
*/
代碼舉例
/**
* 商品類
* @author shc
* @create 2021-05-23 10:57
*/
public class Goods implements Comparable{
private String name;
private double price;
//指明商品比較方式,先按照價格遞增,再按照名字遞增
@Override
public int compareTo(Object o){
System.out.println("==================");
if(o instanceof Goods){
Goods good = (Goods) o;
if(good.price<this.price){
return 1;
}else if(good.price>this.price){
return -1;
}else{
return this.name.compareTo(good.name); //再按照名字排序
// return 0;
}
//方式二
// return Double.compare(this.price,((Goods)o).price);
}
throw new RuntimeException("傳入數據類型不一致錯誤");
}
}
@Test
public void test2(){
Goods[] goods = new Goods[5];
int x = goods.length;
System.out.println(goods.length);//5 是數組本身的長度
goods[0] = new Goods("shubiao",12);
goods[1] = new Goods("diannao",78);
goods[2] = new Goods("erji",10);
goods[3] = new Goods("xianshiqi",1);
goods[4] = new Goods("xian",1);
Arrays.sort(goods,0,goods.length);
for(int i=0;i<goods.length;i++){
System.out.println(goods[i]);
}
}
/*sort方法時回調用compareTo*/
==================
==================
==================
==================
==================
==================
==================
==================
==================
Goods{name='xian', price=1.0}
Goods{name='xianshiqi', price=1.0}
Goods{name='erji', price=10.0}
Goods{name='shubiao', price=12.0}
Goods{name='diannao', price=78.0}
定制排序 Comparator
引入
- 當元素的類型沒有實現java.lang.Comparable接口而又不方便修改代碼, 或者實現了java.lang.Comparable接口的排序規(guī)則不適合當前的操作,那么可以考慮使用 Comparator 的對象來排序,強行對多個對象進行整體排 序的比較。
- 重寫compare(Object o1,Object o2)方法,比較o1和o2的大?。喝绻椒ǚ?回正整數,則表示o1大于o2;如果返回0,表示相等;返回負整數,表示 o1小于o2。 l 可以將 Comparator 傳遞給 sort 方法(如 Collections.sort 或 Arrays.sort), 從而允許在排序順序上實現精確控制。
- 還可以使用 Comparator 來控制某些數據結構(如有序 set或有序映射)的 順序,或者為那些沒有自然順序的對象 collection 提供排序。
- 代碼
Arrays.sort(goods,new Comparator(){//接口可以new嗎?
@Override
public int compare(Object o1,Object o2){
if(o1 instanceof Goods && o2 instanceof Goods){
Goods g1 = (Goods) o1;
Goods g2 = (Goods) o2;
if(g1.getName().equals(g2.getName())){//名字相同時 按照價格遞減
return -Double.compare(g1.getPrice(),g2.getPrice());
}else{
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException(o1+"輸入數據類型錯誤");
//如果有一個數組元素為空的話也會走到這里 因為null instanceof Goods 為false 不會進入if
//如果用的是o1.toString()的話則會是NullPointerException 因為在throwRuntimeException的時候會走到toString()這一步 而null調用toString()則是空指針異常
}
});
兩種排序方式對比
/* 二、Comparable接口與Comparator的使用的對比 * Comparable接口的方式一旦設定,保證了Comparable接口實現類的對象在任意位置都可以比較大小 * Comparator接口屬于臨時性的比較 */
每日一考
畫出如下幾行代碼的內容結構
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
s1+="world"; <---> s1 = s1+"hello"; 右則有變量s1參與,所以拼接結果在堆中

- 如何理解String類的不可變性
- String類是否可以被繼承?為什么?
- String、StringBuffer、StringBuilder三者對比
- String的常用方法有哪些?(至少7個)
length()/charAt()/equals()/compareTo()...
- 每日一考將字符串“2017-08-16”轉化為對應的java.sql.Date類的對象(把頁面?zhèn)魅氲淖址嫒霐祿熘?(是一個解析過程) //其實也可以直接塞進去(但我們一定要會手動轉化)
- 字符串-->java.util.Date date --> longms時間戳- -->java.sql.Date
SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM--dd");
// 解析(字符串String-->日期Date):
java.util.Date utilDate = sdf.parse("2021-02-23");
// 再用date來getTime()(返回的是longms),再放入構造器中
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
DateTimeFormatter
DateTimeFormatterdtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
..............
實例化方式:
new +構造器
單例模式(private構造器)
Calendar.getInstance()//Calendar是一個抽象類,獲取的是他的子類(private構造器)
解釋何為編碼?解碼?何為日期時間的格式化,解析?
編碼:字符串 -> 字節(jié)
解碼:字節(jié) -> 字符串
格式化(format):日期 ->字符串
解析(parse):字符串 -> 日期
自定義Person類如下,如何實現自然排序?(按照名字從小到大)
class Person implements Comparable{
private String name;
@Override
public int compareTo(Object o){
if(o instanceof Person){
Person p = (Person) o;
return this.name.compareTo(p.name);
}
throw new Exception("");
}
}
提供定制排序涉及到的接口的實現類對象,并按Person類的年齡從大到小排序
Comparator cp = new Comparator(){
@Override
public int compare(Object obj1,Object obj2){
if(..)
}
}
JDK8 之前和 JDK8 中與日期、時間相關的類分別有哪些?
JDK8之前 JDK8 java.util.Date 和 java.sql.Date ---> instant (本初子午線的時間) SimpleDateFormat --->DateTimeFormatter Calendar --->LocalDate,LocalTime,LocalDateTime
IDEA常識
- 如何刪除Module?
- Remove ---然后-- > Delete
- 如何導入Module?
- File--->ProjectStructure--->'+'--->導入
- IDEA生成構造器
- Alt+insert
- 快速查詢當前類中某個方法
- ctrl+F12 再輸入方法名
- 快速查詢某個類
- double shift
總結
這篇文章就到這里了,希望能給大家?guī)韼椭蚕M芏喽嚓P注腳本之家的更多內容!
相關文章
Spring Boot如何使用Undertow代替Tomcat
這篇文章主要介紹了Spring Boot如何使用Undertow代替Tomcat,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09
SpringBoot配置lombok與logback過程解析
這篇文章主要介紹了SpringBoot配置lombok與logback過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-05-05

