1.初步嘗試java中的集合使用方式:

public static void main( String [] args )
{
//List 對象
User user=User.builder().id(0).name("huhua"+0).build();
//a.最常見Add的初始化方式
List<User> users=new ArrayList<User>();
for (int i=0;i<100;i++)
{
users.add(User.builder().id(i).name("huhua"+i).build());
}
//b.使用雙花括號在初始化的同時賦值
List<User> users2= new ArrayList<User>() {//這個大括號 就相當於我們 new 接口
{//這個大括號 就是 構造代碼塊 會在構造函數前 調用
this.add(new User(0,"huahua0"));
this.add(new User(1,"huahua1"));
}
};
//c.利用Lists工具類 https://ifeve.com/google-guava/
//c1. Lists 提供了兩個方法:一個是創建一個空列表;。
List<String> list1 = Lists.newArrayList();
list1.add("str1");
list1.add("str2");
list1.add("str3");
//c2.一個是創建空列表的同時遍歷迭代器,將它的值添加到列表中
List<String> list2 = Lists.newArrayList(list1.iterator());
//d. 利用Arrays工具類
List<String> arrList= Arrays.asList( new String[]{"huahu0","huahau1","huahua2"});
//e.Collections 還提供了一個為 List 一次性添加所有元素的方法,彌補了原先 List 只能添加 Collections,而不支持數組的缺憾。
List<String> list3 = new ArrayList<>();
Collections.addAll(list1, new String[]{"str1", "str2", "str3"});
Collections.addAll(list1, "str4", "str5", "str6");
//f.流式轉化:流是 Java8 的新特性,提供了一種類似 SQL 語句從數據庫中查詢數據的方式,通過封裝好的函數和鏈式調用,高階抽象並簡化操作。
//它可以對傳入流內部的元素進行篩選、排序、聚合等中間操作(intermediate operate),最后由最終操作(terminal operation)得到前面處理的結果。
//通過靜態的 Stream.of 方法接收元素,然后通過 collect 方法處理得到最終結果。
List<String> list4 = Stream.of("str1", "str2", "str3").collect(Collectors.toList());
//g.Map方法現在缺失
}
2. 工具類 google-guava 簡介
Guava工程包含了若干被Google的 Java項目廣泛依賴 的核心庫,例如:集合 [collections] 、緩存 [caching] 、原生類型支持 [primitives support] 、並發庫 [concurrency libraries] 、通用注解 [common annotations] 、字符串處理 [string processing] 、I/O 等等。 所有這些工具每天都在被Google的工程師應用在產品服務中。
添加引用
訪問官網地址: https://ifeve.com/google-guava/

目錄
1. 基本工具 [Basic utilities]
讓使用Java語言變得更舒適
1.1 使用和避免null:null是模棱兩可的,會引起令人困惑的錯誤,有些時候它讓人很不舒服。很多Guava工具類用快速失敗拒絕null值,而不是盲目地接受
1.2 前置條件: 讓方法中的條件檢查更簡單
1.3 常見Object方法: 簡化Object方法實現,如hashCode()和toString()
1.4 排序: Guava強大的”流暢風格比較器”
1.5 Throwables:簡化了異常和錯誤的傳播與檢查
2. 集合[Collections]
Guava對JDK集合的擴展,這是Guava最成熟和為人所知的部分
2.1 不可變集合: 用不變的集合進行防御性編程和性能提升。
2.2 新集合類型: multisets, multimaps, tables, bidirectional maps等
2.3 強大的集合工具類: 提供java.util.Collections中沒有的集合工具
2.4 擴展工具類:讓實現和擴展集合類變得更容易,比如創建Collection的裝飾器,或實現迭代器
3. 緩存[Caches]
Guava Cache:本地緩存實現,支持多種緩存過期策略
4. 函數式風格[Functional idioms]
Guava的函數式支持可以顯著簡化代碼,但請謹慎使用它
5. 並發[Concurrency]
強大而簡單的抽象,讓編寫正確的並發代碼更簡單
5.1 ListenableFuture:完成后觸發回調的Future
5.2 Service框架:抽象可開啟和關閉的服務,幫助你維護服務的狀態邏輯
6. 字符串處理[Strings]
非常有用的字符串工具,包括分割、連接、填充等操作
7. 原生類型[Primitives]
擴展 JDK 未提供的原生類型(如int、char)操作, 包括某些類型的無符號形式
8. 區間[Ranges]
可比較類型的區間API,包括連續和離散類型
9. I/O
簡化I/O尤其是I/O流和文件的操作,針對Java5和6版本
10. 散列[Hash]
提供比Object.hashCode()更復雜的散列實現,並提供布魯姆過濾器的實現
11. 事件總線[EventBus]
發布-訂閱模式的組件通信,但組件不需要顯式地注冊到其他組件中
12. 數學運算[Math]
優化的、充分測試的數學工具類
13. 反射[Reflection]
Guava 的 Java 反射機制工具類
3.用現有基本方式實現常見操作
-
3.1 BigDecimal 的用法
a.list中BigDecimal 的求和用法
BigDecimal oneAmountAllTeam = combatTeamEntities.stream().map(CombatTeamEntity::getActivityAmountOne).reduce(BigDecimal::add).get();
b.BigDecimal 的比較函數 int a = bigdemical.compareTo(bigdemical2);

BigDecimal a=new BigDecimal("0.01");
BigDecimal b=new BigDecimal("0.01");
BigDecimal c=new BigDecimal("0.010");
System.out.println(a.equals(b)); //true
System.out.println(a.compareTo(b)); //0
System.out.println(a.equals(c)); //false
System.out.println(a.compareTo(c)); //0
//其中compareTo說明
//a = -1,表示bigdemical小於bigdemical2;
//a = 0,表示bigdemical等於bigdemical2;
//a = 1,表示bigdemical大於bigdemical2;
c.java中舍入方式:
//第一種方法:保留兩位小數
double db = bigDecimalTwo.setScale(2, RoundingMode.HALF_UP).doubleValue();
System.out.println(db);
// 第二種方法:保留兩位小數
DecimalFormat df = new DecimalFormat("#.00");
df.format(bigDecimalTwo);
-
3.2groupby 在java8中的學習
List<Product> prodList = Lists.newArrayList(prod1, prod2, prod3, prod4, prod5);
Map<String, List<Product>> prodMap = prodList.stream().collect(Collectors.groupingBy(item -> item.getCategory() + "_" + item.getName()));
-
3.3map中的遍歷操作
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
-
3.4 Json序列化數據:
a.Json序列化與分序列化用 com.alibaba.fastjson

@ApiModel(description = "優惠券MQ對接實體模型")
@Data
public class MQCouponCostShareDTO {
/// <summary>
/// 優惠券主鍵
/// </summary>
@JsonProperty("CouponId")
Long couponId;
/// <summary>
/// 升級后的 優惠券id
/// </summary>
@JsonProperty("ProofId")
String couponCode;
/// <summary>
/// 優惠券領取規則主鍵
/// </summary>
@JsonProperty("GetRuleId")
String couponBatchId;
}
MQCouponCostShareDTO mqCouponCostShareDTO=new MQCouponCostShareDTO();
String strJson="{\"BusinessId\":0,\"CodeChannel\":\"GroupBuyingCoupon\",\"SourceType\":\"Tuhu\",\"CouponId\":0,\"ProofId\":\"3100001098\",\"GetRuleId\":12485,\"GetRuleGUID\":\"1283c0c9-61ca-40bd-9813-ea789523eeec\",\"CreateTime\":\"2021-08-05T17:26:00.535+08:00\",\"PromotionType\":0,\"EndTime\":\"2021-08-31T00:00:00.000+08:00\",\"BatchID\":0,\"StartTime\":\"2021-08-05T00:00:00.000+08:00\",\"OrderId\":0,\"OperateTime\":\"2021-08-05T17:26:00.535+08:00\",\"OperateType\":99,\"Author\":\"system\",\"DepartmentId\":39,\"DepartmentName\":\"測試用123/測試用123-2/測試用123-3\",\"SFIDs\":null,\"IntentionId\":40,\"IntentionName\":\"測試用途\",\"BusinessName\":null,\"CompanyNumber\":\"1001\",\"Version\":\"3FAxcybLLIMRi\",\"ProductBusinessId\":\"2\",\"ShareDetails\":[{\"SFIDs\":\"112345|212345|312345\",\"Percentage\":100.0,\"DepartmentId\":39,\"DepartmentName\":\"測試用123/測試用123-2/測試用123-3\"}]}";
MQCouponCostShareDTO objectdto2= JsonConvertUtils.jsonToObject(strJson, MQCouponCostShareDTO.class);
//模型的轉換 Json序列化過程中
Object object= JSONObject.parse(strJson); //正常轉換
//MQCouponCostShareDTO objectdto= (MQCouponCostShareDTO)JSONObject.parse(strJson);//調用異常
MQCouponCostShareDTO objectdto=JSONObject.parseObject(strJson,MQCouponCostShareDTO.class); //直接進行類型裝換
//按照Json proporty 中的內容進行反序列化
//按照Json proporty中的內容進行序列化
String str4=JsonConvertUtils.objectToJson(objectdto2);
String str2=JSONObject.toJSONString(object); //str2 是正常的操作
//空對象的兌換
Object object1= JSONObject.parse(null); // null
String str3=JSONObject.toJSONString(null); //"null"
System.out.println(strJson.length());
b.通過json格式傳過來的日期字符串,無法通過json直接轉化成Date日期類型。

請求數據格式為: ‘yyyy-MM-dd HH:mm:ss’,但是在接收到數據的時候,需要通過json把數據轉化成ElecMeterDataApi對象。json轉化的時候,默認的時間格式是 'yyyy-MM-dd’T’HH:mm:ss.SSS’,所以就會出現上面的異常
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date dataReadTime;
-
3.5String的常用方法
a.StringUtils.isNotEmpty(a) a=null 為false
-
3.6異常塊 try-catch-finally
a. 下述4種特殊情況時,finally塊都不會被執行
1)在finally語句塊中發生了異常。
2)在前面的代碼中用了System.exit()退出程序。
3)程序所在的線程死亡。
4)關閉CPU。
b.函數返回值問題:
1)finally里的 return語句會把 try/catch塊里的 return語句效果給覆蓋掉
2) finally里不存在return語句: 參考 https://mp.weixin.qq.com/s/FzVAXjk7Oj4ycLRH1nKQ1w
對於這種情況我的理解就是在 return的的時候會把返回值壓入棧,並把返回值賦值給棧中的局部變量, 最后把棧頂的變量值作為函數返回值。所以在 finally中的返回值就會覆蓋 try/catch中的返回值,如果 finally中不執行 return語句,在 finally中修改返回變量的值,不會影響返回結果。

@SpringBootTest
public class CatchTests {
public static int test() {
int b=1;
try {
int a = 2 / 0;
System.out.println("try");
return a;
} catch (Exception e) {
System.out.println("catch");
b=2;
return b;
} finally {
b=3;
System.out.println("finally");
}
}
@Test
public void catchReturn(){
System.out.println(test());
System.out.println("程序正常運行結束");
/* catch
finally
2
程序正常運行結束*/
}
}
c.聲明異常:throws 參考:https://blog.csdn.net/weixin_39547298/article/details/110616814
1)當開發者在定義方法時,事先知道方法在調用時會出現異常,但不知道該如何處理,此時可以在該方法上聲明異常。表示該方法在調用過程中 會出現異常,請調用者自行處理。
在java中使用throws 聲明異常。一個方法可以聲明多個異常,用,號分割,寫法如下:
public void test2()throws IOException,RuntimeException{2 //有異常出得代碼,在此處沒有處理3 }
2)聲明異常與方法重載、方法重寫的關系
聲明異常與方法重載的關系:聲明異常和方法重載沒有任何關系。
聲明異常與方法重寫的關系:
如果父類方法聲明了異常(檢查時或運行時),子類方法可以完全遵循父類異常,也可以不聲明異常。
如果父類方法沒有聲明異常,子類可以不聲明異常,也可以聲明RuntimeException,但不能聲明Exception。
如果父類聲明了運行時異常,子類可以完全遵循父類異常,也可以不聲明異常。
3)異常處理:
異常處理:如果一直都沒有處理(即沒有用try-catch等語句)異常會把異常拋給調用者,一直拋到main函數處,如果在main函數中也沒有處理繼續在main函數后拋出異常,這時候會拋給jvm處理。
d.自定義異常 參考:https://blog.csdn.net/weixin_39547298/article/details/110616814
自定義異常步驟:
•[1] 確定異常類型.繼承Excepion 或者RuntimeException
•[2] 編寫自定義異常類,並實現構造方法
•[3] 在方法需要的地方手動聲明並拋出異常。
public class myException extends Exception { public myException() { super(); } public myException(String message) { super(message); } //自定義異常中的方法,以符合自己的需求 public void showInfo() { System.out.println(super.getMessage()+"@Line:"); }}
-
3.7 JAVA 中的 OPTIONAL
簡介: Optional 類主要解決的問題是臭名昭著的空指針異常(NullPointerException),本質上,這是一個包含有可選值的包裝類,這意味着 Optional 類既可以含有對象也可以為空,Optional 是 Java 實現函數式編程的強勁一步,並且幫助在范式中實現。
使用簡介:

public class User {
private String position;
public Optional<String> getPosition() {
return Optional.ofNullable(position);
}
}
User user = new User("john@gmail.com","1234");
User user2 = new User("anna@gmail.com", "1234");
User result = Optional.ofNullable(user).orElse(user2);
//orElseGet會執行作為參數傳入的 Supplier(供應者) 函數式接口
User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
//option轉換成其他類型
User user = new User("anna@gmail.com", "1234");
String email = Optional.ofNullable(user)
.map(u -> u.getEmail()).orElse("default@gmail.com");
String position = Optional.ofNullable(user)
.flatMap(u -> u.getPosition()).orElse("default");
//過濾器
Optional<User> result = Optional.ofNullable(user)
.filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
創建函數: of() 與ofNullable(),區別——兩個方法的不同之處在於如果你把 null 值作為參數傳遞進去,of() 方法會拋出 NullPointerException
賦值默認值:orElse(),orElseGet(),區別——兩個 Optional 對象都包含非空值,兩個方法都會返回對應的非空值。不過,orElse() 方法仍然創建了 User 對 象。與之相反,orElseGet() 方法不創建 User 對象。
轉換值: map() 和 flatMap(),map() 對值應用(調用)作為參數的函數,然后將返回的值包裝在 Optional 中,flatMap() 也需要函數作為參數,並對值調用這個 函數,然后直接返回結果。
過濾值:filter() 接受一個 Predicate 參數
4.java8中新特性的學習
參考: https://blog.csdn.net/u014231523/article/details/102535902
map的遍歷查詢:https://blog.csdn.net/tjcyjd/article/details/11111401
5.MySQL的基本屬性
a.MySql中的varchar長度究竟是字節還是字符MySql中的varchar長度究竟是字節還是字符
version4之前,按字節 ;version5之后,按字符
6.java 中的位運算
6.1移位操作:
其中位運算中:正數的反碼,補碼是同一個;負數位運算是對補碼進行的運算
反碼: 反碼與原碼相同,負數的反碼在原碼的基礎上,符號位不變,其余的按位取反
補碼:正數的補碼就是原碼本身,負數的補碼是它的反碼+1
參考網址: https://www.cnblogs.com/chuijingjing/p/9405598.html
<<表示左移,不分正負數,低位補0;
>>表示右移,如果該數為正,則高位補0,若為負數,則高位補1;
>>>表示無符號右移,也叫邏輯右移,即若該數為正,則高位補0,而若該數為負數,則右移后高位同樣補0
6.2或(|)、並(&)操作
7.異步線程池
原理解析:https://blog.csdn.net/RoxyJ/article/details/105758526
原理解析加代碼分析代碼使用:
https://www.jianshu.com/p/9a8c81066201
https://zhuanlan.zhihu.com/p/65556060
美團技術團隊:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html
1)如果當前運行的線程少於corePoolSize,則創建新線程來執行任務(注意,執行這一步驟需要獲取全局鎖)。
2)如果運行的線程等於或多於corePoolSize,則將任務加入BlockingQueue。
3)如果無法將任務加入BlockingQueue(隊列已滿),則創建新的線程來處理任務(注意,執行這一步驟需要獲取全局鎖)。
4)如果創建新線程將使當前運行的線程超出maximumPoolSize,任務將被拒絕,並調用RejectedExecutionHandler.rejectedExecution()方法。
系統中封裝的抽象類:
1.Executors是一個線程池工廠類,里面有許多靜態方法,供開發者調用 參考:jianshu.com/p/61c715ed3d23
2.ThreadPoolExecutor :線程池的執行策略。Executors中的線程池都是對ThreadPoolExecutor參數不同的設置,達到不同的實際效果。
3.飽和策略:https://blog.csdn.net/qq_25806863/article/details/71172823 ,4中常用策略,還可以自定義執行冊羅
4. 源碼分析直接參考:https://www.jianshu.com/p/9a8c81066201
5.測試用例分析:https://blog.csdn.net/qq_14861089/article/details/80974290
測試用例

/*
* 1.核心線程的執行
* 2.等待隊列的正常執行
* 3.非核心線程的執行
* 4.飽和策略的執行
* */
@Test
public void threadPoolExecutorTest() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3), new ThreadPoolExecutor.CallerRunsPolicy());
//往線程池中循環提交線程
for (int i = 0; i < 10; i++) {
//創建線程類對象
MyThread1 myTask = new MyThread1(i);
//開啟線程
executor.execute(myTask);
//獲取線程池中線程的相應參數
System.out.println("線程池中線程數目:" +executor.getPoolSize() + ",隊列中等待執行的任務數目:"+executor.getQueue().size() + ",已執行完的任務數目:"+executor.getCompletedTaskCount());
}
try {
System.out.println("==1==線程池中線程數目:" +executor.getPoolSize() + ",隊列中等待執行的任務數目:"+executor.getQueue().size() + ",已執行完的任務數目:"+executor.getCompletedTaskCount());
Thread.sleep(6000);
System.out.println("==2==線程池中線程數目:" +executor.getPoolSize() + ",隊列中等待執行的任務數目:"+executor.getQueue().size() + ",已執行完的任務數目:"+executor.getCompletedTaskCount());
System.out.println("執行另一批線程----");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//往線程池中循環提交線程
for (int i = 0; i < 6; i++) {
//創建線程類對象
MyThread1 myTask = new MyThread1(i);
//開啟線程
executor.execute(myTask);
//獲取線程池中線程的相應參數
System.out.println("2線程池中線程數目:" +executor.getPoolSize() + ",隊列中等待執行的任務數目:"+executor.getQueue().size() + ",已執行完的任務數目:"+executor.getCompletedTaskCount());
}
//待線程池以及緩存隊列中所有的線程任務完成后關閉線程池。
executor.shutdown();
System.out.println("關閉線程池----");
try {
Thread.sleep(20000);
System.out.println("主線程end----");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("==3==線程池中線程數目:" +executor.getPoolSize() + ",隊列中等待執行的任務數目:"+executor.getQueue().size() + ",已執行完的任務數目:"+executor.getCompletedTaskCount());
}
public class MyThread1 implements Runnable{
private int num;
public MyThread1() {
super();
// TODO Auto-generated constructor stub
}
public MyThread1(int num) {
super();
this.num = num;
// TODO Auto-generated constructor stub
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("正在執行task " + num);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("task " + num + "執行出錯");
e.printStackTrace();
}
System.out.println("task " + num + "執行完畢");
}
}
8.跨域 參考文件:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
9.MybatisPlus的條件構造器Wrapper常用的構造函數總結
https://blog.csdn.net/weixin_44870909/article/details/108761753