// ::表示引用疲牵,比如類的構(gòu)造方法环凿,對象方法侨拦,靜態(tài)方法的引用
stream.forEach(System.out::println);
等價
stream.forEach(item->System.out.println(item));
java 8中stream相關(guān)用法
注意:Arrays.asList得到的只是一個 Arrays 的內(nèi)部類氧苍,一個原來數(shù)組的視圖 List磕潮,因此如果對它進行增刪操作會報錯疙教。用 ArrayList 的構(gòu)造器可以將其轉(zhuǎn)變成真正的 ArrayList。
String[] str = new String[]{"1","2","3"};
ArrayList al = new ArrayList(Arrays.asList(str));
2.MyBatis-Plus | 最簡單的查詢操作教程(Lambda)
4.VO與PO的區(qū)別:
- VO是用new關(guān)鍵字創(chuàng)建韧拒,由GC回收的淹接。PO是向數(shù)據(jù)庫中添加新數(shù)據(jù)時創(chuàng)建十性,刪除數(shù)據(jù)庫中數(shù)據(jù)時刪除的。并且它只能存活在一個數(shù)據(jù)庫連接中塑悼,當連接斷開時劲适,將被銷毀。
- VO是值對象厢蒜,精確點講它是業(yè)務(wù)對象霞势,是存活在業(yè)務(wù)層的,是業(yè)務(wù)邏輯使用的斑鸦,它存活的目的就是為數(shù)據(jù)提供一個生存的地方愕贡。PO是有狀態(tài)的,每個屬性代表其當前的狀態(tài)巷屿。它是物理數(shù)據(jù)的對象表示固以。使用它,可以使我們的程序與物理數(shù)據(jù)解耦嘱巾,并且可以簡化對象數(shù)據(jù)與物理數(shù)據(jù)之間的轉(zhuǎn)換憨琳。
- VO的屬性是根據(jù)當前業(yè)務(wù)的不同而不同的,也就是說旬昭,它的每一個屬性都一一對應當前業(yè)務(wù)邏輯所需要的數(shù)據(jù)的名稱篙螟。PO的屬性是跟數(shù)據(jù)庫表的字段一一對應的。
- VO是獨立的Java Object问拘。PO是由Hibernate納入其實體容器(Entity Map)的對象遍略,它代表了與數(shù)據(jù)庫中某條記錄對應的Hibernate實體,PO的變化在事務(wù)提交時將反應到實際數(shù)據(jù)庫中骤坐。
- 不用po代替vo的主要原因還有業(yè)務(wù)層的方法的參數(shù)和返回類型不能是POJO墅冷,因為當POJO處于持久化狀態(tài)時,會同步更新數(shù)據(jù)庫或油,會帶來一定的危險性,即在用戶不知覺的情況下會對數(shù)據(jù)進行修改驰唬,所以顶岸,不能在控制器中對POJO進行操作,而用VO代替叫编。使用VO可以避免Session已關(guān)閉的異常辖佣。
5.單元測試
- @Mock:創(chuàng)建一個Mock類,模擬類中的方法是空的搓逾,只負責返回模擬結(jié)果卷谈。
- @InjectMocks:創(chuàng)建一個真實的類實例。然后將用@Mock(或@Spy)注解創(chuàng)建的mock對象注入到用該實例中霞篡。
- 在單元測試中世蔗,沒有啟動 spring 框架端逼,此時就需要通過
@ InjectMocks完成依賴注入。 - @InjectMocks會將帶有@Spy 和@Mock 注解的對象嘗試注入到被 測試的目標類中污淋。
- 單元測試只負責測試@InjectMocks類中方法顶滩。對應依賴的@Mock類,只需要它返回的模擬結(jié)果寸爆。不對@Mock類中的方法測試和負責礁鲁。
// 判斷某字符串是否為空,為空的標準是 str==null 或 str.length()==0
StringUtils.isEmpty()
StringUtils.isNotEmpty()
// 是否為 null
// 是否為 ""
// 是否為空字符串(引號中間有空格) 如: " "赁豆。
StringUtils.isBlank()
StringUtils.tokenizeToStringArray()
7.ObjectUtils.isEmpty()
8.CollectionUtils.isEmpty()
CollectionUtils.arrayToList()
9.MapUtils.isNotEmpty()
10.// 對象的拷貝
BeanUtils.copyPropertiies(source,result)
11.EnumUtils.convertEnumToCode(a)
EnumUtils.convertEnumToDesc(b)
for(Map.Entry<fa,fb> entry: funcs.entrySet()){
}
13.Collections.addAll()
List<String> taskTypes = tasks.stream().map(Entity::getTaskType).distinct().collect(Collectors.toList());
.stream().collect(Collectors.toMap(a->a.getBizid,b->b.getBizType))
// REQUIRED:支持當前事務(wù)仅醇,如果當前沒有事務(wù),就新建一個事務(wù)魔种。這是最常見的選擇析二。
@Transaction(propagation=Propagation.REQUIED,rollbackFor=Throwable.class)
// NOT_SUPPORTED:以非事務(wù)方式執(zhí)行操作,如果當前存在事務(wù)务嫡,就把當前事務(wù)掛起甲抖。
@Transaction(propagation=Propagation.NOT_SUPPORTED)
// Require_New:不管當前有沒有事務(wù),會新開一個事務(wù)
@Transaction(propagation=Propagation.Require_New)
類調(diào)用自身函數(shù)時心铃,不會產(chǎn)生動態(tài)代理方法准谚,此時事務(wù)注解的功能會失效。
A去扣,B兩個方法柱衔。可能在同一個類中愉棱,或不同類中唆铐。
A調(diào)用B:
(1)A有事務(wù),事務(wù)正常生效奔滑。
(2)A沒有事務(wù)艾岂,B有事務(wù),事務(wù)失效
(3)A沒有事務(wù)朋其,B有事務(wù)王浴。A注入類自身類,并且通過自身類去調(diào)用B梅猿。這種情況B的事務(wù)正常生效氓辣。
16.orgIds.stream().mapToInt(Integer::valueof).toArray()
17.//獲取Spring容器中指定類型的所有JavaBean對象
Map<String, AbstractTaskHandler> handlerMap = SpringContextUtils.getBeanOfType(AbstractTaskHandler.class);
AbstractTaskHandler handle = SpringContextUtils.getBean(name ,AbstractTaskHandler.class)
18.轉(zhuǎn)int:
Integer.parseInt()
aa.intValue()
19.compareTo方法:
// 字符串轉(zhuǎn)BigDecimal
BigDecimal b1 = new BigDecimal("-121454125453.145");
// -1:小于袱蚓; 0 :等于钞啸; 1 :大于
if(b1.compareTo(BigDecimal.ZERO)==-1) {
System.out.println("金額為負數(shù)!");
}
最常見的多態(tài)就是將子類傳入父類參數(shù)中,運行時調(diào)用父類方法時通過傳入的子類決定具體的內(nèi)部結(jié)構(gòu)或行為体斩。
Liskov替換原則:子類可以替換基類梭稚,但是基類不一定能替換子類。通俗講子類可以擴展父類的功能硕勿,但不能改變父類原有的功能哨毁。
依賴倒置原則:依賴于抽象,就是對接口編程源武,不要對實現(xiàn)編程
接口隔離原則:使用多個小的專門的接口扼褪,而不要使用一個大的總接口
多態(tài)的3個必要條件:
有類繼承或者接口實現(xiàn)
子類要重寫父類的方法
父類的引用指向子類的對象
繼承的根本原因是因為要復用,而實現(xiàn)的根本原因是需要定義一個標準粱栖。
Java中支持一個類同時實現(xiàn)多個接口话浇,但是不支持同時繼承多個類。
在接口中只能定義全局常量(static final)和無實現(xiàn)的方法(Java 8以后可以有defult方法)闹究;而在繼承中可以定義屬性方法,變量,常量等幔崖。
組合與繼承的區(qū)別和聯(lián)系
- 在繼承結(jié)構(gòu)中,父類的內(nèi)部細節(jié)對于子類是可見的渣淤。所以我們通常也可以說通過繼承的代碼復用是一種白盒式代碼復用赏寇。(如果基類的實現(xiàn)發(fā)生改變,那么派生類的實現(xiàn)也將隨之改變价认。這樣就導致了子類行為的不可預知性嗅定;)
- 組合是通過對現(xiàn)有的對象進行拼裝(組合)產(chǎn)生新的、更復雜的功能用踩。因為在對象之間渠退,各自的內(nèi)部細節(jié)是不可見的,所以我們也說這種方式的代碼復用是黑盒式代碼復用脐彩。(因為組合中一般都定義一個類型碎乃,所以在編譯期根本不知道具體會調(diào)用哪個實現(xiàn)類的方法)
- 繼承,在寫代碼的時候就要指名具體繼承哪個類惠奸,所以梅誓,在編譯期就確定了關(guān)系。(從基類繼承來的實現(xiàn)是無法在運行期動態(tài)改變的佛南,因此降低了應用的靈活性证九。)
- 組合,在寫代碼的時候可以采用面向接口編程共虑。所以,類的組合關(guān)系一般在運行期確定呀页。
構(gòu)造函數(shù)與默認構(gòu)造函數(shù)
- 構(gòu)造器沒有返回類型妈拌,不會被繼承,且可以有范圍修飾符。構(gòu)造器的函數(shù)名稱必須和它所屬的類的名稱相同尘分。
- 默認構(gòu)造函數(shù)一般會把成員變量的值初始化為默認值猜惋,如int -> 0,Integer -> null培愁。 它承擔著初始化對象數(shù)據(jù)成員的任務(wù)著摔。
Java中共有三種變量,分別是類變量定续、成員變量和局部變量谍咆。他們分別存放在JVM的方法區(qū)、堆內(nèi)存和棧內(nèi)存中私股。
對于不同的硬件和操作系統(tǒng)摹察,最主要的區(qū)別就是指令不同。
有了Java虛擬機倡鲸,想要執(zhí)行a+b操作供嚎,A操作系統(tǒng)上面的虛擬機就會把指令翻譯成10001000,B操作系統(tǒng)上面的虛擬機就會把指令翻譯成11101110峭状。
Java的平臺無關(guān)性是建立在Java虛擬機的平臺有關(guān)性基礎(chǔ)之上的克滴,是因為Java虛擬機屏蔽了底層操作系統(tǒng)和硬件的差異。
Java中引用數(shù)據(jù)類型參數(shù)(如對象)也是按值傳遞給方法的优床。這意味著劝赔,當方法返回時,傳入的引用仍然引用與以前相同的對象羔巢。但是望忆,如果對象字段具有適當?shù)脑L問級別,則可以在方法中更改這些字段的值竿秆。
Java傳參只有值傳遞启摄,只不過是把對象的引用當做值傳遞給方法。也就是將對象的地址的拷貝傳遞給被調(diào)函數(shù)的形式參數(shù)幽钢。
mybatispuls里面getOne需要注意返回多條結(jié)果會報錯歉备。需要在queryWrapper中加.last("FETCH FIRST 1 ROWS ONLY WITH UR")
32.For循環(huán)和While區(qū)別:
從應用場景方面考慮:
for循環(huán)適用于已知循環(huán)次數(shù),while循環(huán)適用于未知循環(huán)次數(shù)匪燕。
那么在已知循環(huán)次數(shù)時蕾羊,最好選擇for循環(huán);
如果循環(huán)次數(shù)是未知的帽驯。最好選擇while循環(huán).
從內(nèi)存角度考慮:
局部變量在棧內(nèi)存中存在,當for循環(huán)語句結(jié)束,那么變量會及時被gc(垃圾回收器)及時的釋放掉,不浪費空間龟再;
如果使用循環(huán)之后還想去訪問循環(huán)語句中控制那個變量,使用while循環(huán)。
Java中的整型主要包含byte尼变、short利凑、int和long這四種,表示的數(shù)字范圍也是從小到大的,之所以表示范圍不同主要和他們存儲數(shù)據(jù)時所占的字節(jié)數(shù)有關(guān)哀澈。
- byte:byte用1個字節(jié)來存儲牌借,范圍為-128(-27)到127(27-1),在變量初始化的時候割按,byte類型的默認值為0膨报。
- short:short用2個字節(jié)存儲,范圍為-32,768 (-2^15)到32,767 (2^15-1)适荣,在變量初始化的時候现柠,short類型的默認值為0,一般情況下束凑,因為Java本身轉(zhuǎn)型的原因晒旅,可以直接寫為0。
- int:int用4個字節(jié)存儲汪诉,范圍為-2,147,483,648 (-2^31)到2,147,483,647 (2^31-1)废恋,在變量初始化的時候,int類型的默認值為0扒寄。
- long:long用8個字節(jié)存儲鱼鼓,范圍為-9,223,372,036,854,775,808 (-2^63)到9,223,372,036, 854,775,807 (2^63-1),在變量初始化的時候该编,long類型的默認值為0L或0l迄本,也可直接寫為0。
- 單精度浮點數(shù)在計算機存儲器中占用4個字節(jié)(32 bits)课竣,利用“浮點”(浮動小數(shù)點)的方法嘉赎,可以表示一個范圍很大的數(shù)值。
- 比起單精度浮點數(shù)于樟,雙精度浮點數(shù)(double)使用 64 位(8字節(jié)) 來存儲一個浮點數(shù)公条。
- 由于計算機中保存的小數(shù)其實是十進制的小數(shù)的近似值,并不是準確值迂曲,所以靶橱,千萬不要在代碼中使用浮點數(shù)來表示金額等重要的指標。建議使用BigDecimal或者Long(單位為分)來表示金額路捧。
對于不需要任何準確計算精度的數(shù)字可以直接使用float或double关霸,但是如果需要精確計算的結(jié)果,則必須使用BigDecimal類杰扫,而且使用BigDecimal類也可以進行大數(shù)的操作队寇。
在Java中,==比較的是對象應用章姓,而equals比較的是值英上。
Integer a = 12;
Integer b =12;
a==b; // true
Integer c = 1234;
Integer d =1234;
c==d; // false
所有相同類型的包裝類對象之間的比較炭序,推薦使用equals方法比較。避免IntegerCache大坑苍日。
一旦一個string對象在堆中被創(chuàng)建出來,他就無法被修改窗声。特別要注意的是相恃,String類的所有方法都沒有改變字符串本身的值,都是返回了一個新的對象笨觅。
如果你需要一個可修改的字符串拦耐,應該使用StringBuffer 或者 StringBuilder。否則會有大量時間浪費在垃圾回收上见剩,因為每次試圖修改都有新的string對象被創(chuàng)建出來杀糯。
String 字符串常量
StringBuffer 字符串變量(線程安全)
StringBuilder 字符串變量(非線程安全,項目中常用)
String.valueOf(i)也是調(diào)用Integer.toString(i)來實現(xiàn)的
Long.valueOf()注意空字符串和null異常
Collection 是一個集合接口苍苞。 它提供了對集合對象進行基本操作的通用接口方法固翰。Collection接口在Java 類庫中有很多具體的實現(xiàn)。是list羹呵,set等的父接口骂际。
Collections 是一個包裝類。 它包含有各種有關(guān)集合操作的靜態(tài)多態(tài)方法冈欢。此類不能實例化歉铝,就像一個工具類,服務(wù)于Java的Collection框架凑耻。
List特點:元素有放入順序太示,元素可重復
Set特點:元素無放入順序,元素不可重復
JDK中序列化和反序列化的API:
- java.io.ObjectInputStream:對象輸入流香浩。
該類的readObject()方法從輸入流中讀取字節(jié)序列类缤,然后將字節(jié)序列反序列化為一個對象并返回。 - java.io.ObjectOutputStream:對象輸出流弃衍。
該類的writeObject(Object obj)方法將傳入的obj對象進行序列化呀非,把得到的字節(jié)序列寫入到目標輸出流中進行輸出。
41.序列化
當試圖對?個對象進行序列化的時候镜盯, 如果遇到不支持Serializable
接口的對象岸裙。 在此情況下, 將拋NotSerializableException
速缆。
如果要序列化的類有父類言沐, 要想同時將在父類中定義過的變量持久化下來, 那么父類也應該實現(xiàn)java.io.Serializable
接口葫录。
transient 關(guān)鍵字的作用是控制變量的序列化, 在變量聲明前加上該關(guān)鍵字幢尚, 可以阻?該變量被序列化到?件中, 在被反序列化后翅楼, transient 變量的值被設(shè)為初始值尉剩, 如 int 型的是 0,對象型的是 null毅臊。
異常鏈
try {
} catch (IOException e) {
throw new SampleException("Other IOException", e);
}
在此示例中理茎,當捕獲到IOException時,將創(chuàng)建一個新的SampleException異常管嬉,并附加原始的異常原因皂林,并將異常鏈拋出到下一個更高級別的異常處理程序。
如果try中有return語句蚯撩, 那么finally中的代碼還是會執(zhí)?础倍。因為return表?的是整個?法體返回, 所以胎挎,finally中的語句會在return之前執(zhí)?沟启。
有些特殊字符是無法在URL中展示的,所以呀癣,遇到這種字符美浦,如中文,就需要進行URLEncode編碼和解碼项栏。
int和Integer的轉(zhuǎn)換浦辨。從反編譯得到內(nèi)容可以看出,在裝箱的時候自動調(diào)用的是Integer的valueOf(int)方法沼沈。而在拆箱的時候自動調(diào)用的是Integer的intValue方法流酬。
當我們使用enmu來定義一個枚舉類型的時候,編譯器會自動幫我們創(chuàng)建一個final類型的類繼承Enum類列另,所以枚舉類型不能被繼承芽腾。
在java 7中,數(shù)值字面量页衙,不管是整數(shù)還是浮點數(shù)摊滔,都允許在數(shù)字之間插入任意多個下劃線。這些下劃線不會對字面量的數(shù)值產(chǎn)生影響店乐,目的就是方便閱讀艰躺。
比如:
public class Test {
public static void main(String... args) {
int i = 10_000;
System.out.println(i);
}
}
增強for循環(huán),實現(xiàn)原理其實就是使用了普通的for循環(huán)和迭代器眨八。
從Java 7開始腺兴,jdk提供了一種更好的方式關(guān)閉資源,使用try-with-resources語句廉侧。
之前是
try {}
catch(){}
finally{}
現(xiàn)在是
try(資源){}
catch(){}
for (Student stu : students) {
if (stu.getId() == 2)
students.remove(stu);
}
以上增強型for循環(huán)刪除元素時會拋出ConcurrentModificationException異常页响。
解決方法:用傳統(tǒng)for循環(huán)或者用Iterator 本身的方法remove()來刪除對象
java普通for循環(huán)和增強for循環(huán)中做集合增刪會不會出錯篓足?
無論何時這個equals方法被重寫那么都是有必要去重寫hashCode方法,這個是因為為了維持hashCode的一種約定闰蚕,相同的對象必須要有相同的hashCode值栈拖。
被synchronized修飾的代碼塊及方法,在同一時間没陡,只能被單個線程訪問辱魁。
在springboot yml配置文件中寫以0開頭的字符串,當寫為01001時诗鸭,通過注解獲取到的值是1001,springboot會自動的把0過濾掉参滴。因此在使用0開頭的字符串時强岸,應該寫為“01001” 。
原子性是指一個操作是不可中斷的砾赔,要全部執(zhí)行完成蝌箍,要不就都不執(zhí)行。
在pom.xml中通過properties元素用戶可以自定義一個或多個Maven屬性暴心,然后在POM的其他地方使用${屬性名}的方式引用該屬性妓盲。這種做法的最大意義在于消除重復和統(tǒng)一管理。
try-with-resources 是 JDK 7 中一個新的異常處理機制专普。
所有實現(xiàn)了 [java.lang.AutoCloseable]接口(其中悯衬,它包括實現(xiàn)了 [java.io.Closeable] 的所有對象),可以使用作為資源檀夹。
<trim prefix="Where" prefixOverrides="AND|OR">
</trim>
對trim中的sql筋粗,前綴添加where,
移除sql開始的AND|OR
判空的代碼Java8新處理-Optional。
Optional.ofNullable(...).orElse("");
Optional<...> abc = ...;
abc.isPresent()? ... : null炸渡;
而常見的判斷Optional結(jié)果的方法有娜亿,orElse()、isPresent()蚌堵、get()买决、empty()、map()吼畏、flatMap()督赤。
java8 Optional理解及示例
Java的堆是一個運行時數(shù)據(jù)區(qū),類的對象從堆中分配空間宫仗。
堆的優(yōu)勢是在運行時動態(tài)地分配內(nèi)存空間够挂,需要多少內(nèi)存空間不必事先告訴編譯器。
堆缺點是藕夫,由于需要在運行時動態(tài)分配內(nèi)存孽糖,所以存取速度較慢枯冈。
棧中主要存放一些基本數(shù)據(jù)類型的變量(byte,short办悟,int尘奏,long,float病蛉,double炫加,boolean,char)和對象的引用铺然。
棧的優(yōu)勢是俗孝,存取速度比堆快,棧數(shù)據(jù)可以共享魄健。
棧缺點是赋铝,存放在棧中的數(shù)據(jù)占用多少內(nèi)存空間需要在編譯時確定下來,缺乏靈活性沽瘦。
與 Tomcat 相比革骨,Jetty 可以同時處理大量鏈接并且長時間的保持這些鏈接,例如析恋,一些 Web 聊天應用非常適合用 Jetty 服務(wù)器良哲,比如說淘寶的 Web 版旺旺。
- 加載器的任務(wù)就是把處于虛擬機外部存儲空間的字節(jié)碼資源載入到虛擬機運行時環(huán)境里助隧。
- 解釋器每次運行程序時都要一行一行先轉(zhuǎn)成另一種語言再運行筑凫。
- JIT編譯器工作階段基本是java程序運行期的最后階段了,它的工作是將加載的字節(jié)碼轉(zhuǎn)換為機器碼喇颁。當使用JIT編譯器時漏健,硬件可以執(zhí)行JIT編譯器生成的機器碼,而不是讓JVM通過解釋器重復解釋執(zhí)行相同的字節(jié)碼導致相對冗長的翻譯過程橘霎。這樣可以帶來執(zhí)行速度的性能提升蔫浆。
redis可以給每個key設(shè)置一個過期時間,這樣當達到過期時間之后直接刪除姐叁。像redis是直接使用單線程處理瓦盛,所以就不存在線程安全問題。分布式緩存如redis是有持久化功能的外潜。
- 緩存穿透是指大量查詢一些數(shù)據(jù)庫中不存在的數(shù)據(jù)原环,從而影響數(shù)據(jù)庫的性能。
- 緩存擊穿是指并發(fā)用戶特別多处窥,緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)
- 緩存雪崩是指由于某種原因造成Redis突然失效嘱吗,從而造成MySQL瞬間壓力驟增,進而嚴重影響MySQL性能甚至造成MySQL服務(wù)宕機。
如果RuntimeException沒有被捕獲而直達main()谒麦,那么程序退出前將調(diào)用異常的printStackTrace()方法俄讹。
如果像是訂單庫等數(shù)據(jù)量非常龐大,一般會進行分庫分表绕德。這個時候不建議使用數(shù)據(jù)庫的 id 作為唯一標識患膛,而應該使用分布式的高并發(fā)唯一 id 生成器來生成,并在數(shù)據(jù)表中使用另外的字段來存儲這個唯一標識耻蛇。
spring默認的實例化方法就是無參構(gòu)造函數(shù)實例化踪蹬。
如我們在xml里定義的 <bean id="xxx" class="yyy"/> 以及用注解標識的bean都是通過默認實例化方法實例化的。
Spring Boot Bean生命周期
this() 就是調(diào)用自己的無參構(gòu)造方法臣咖,和super()一個道理跃捣。
在子類的構(gòu)造方法中,只要里面沒有顯示的通過super去調(diào)用父類相應的構(gòu)造方法夺蛇,默認都是調(diào)用super()枝缔,即無參構(gòu)造方法,因此要確保父類有相應的構(gòu)造方法蚊惯。
Spring Boot緩存注解@Cacheable、@CacheEvict灵临、@CachePut使用
在實際的開發(fā)中截型,看到有一些對象被手動賦值為NULL,很大可能就是為了“特意提醒”JVM這塊資源可以進行垃圾回收了儒溉。
在Java中宦焦,其實是通過值傳遞實現(xiàn)的參數(shù)傳遞,只不過對于Java對象的傳遞顿涣,傳遞的內(nèi)容是對象的引用波闹。絕對不能認為Java中有引用傳遞。
Vector與ArrayList一樣涛碑,也是通過數(shù)組實現(xiàn)的精堕,不同的是它支持線程的同步,即某一時刻只有一 個線程能夠?qū)?Vector蒲障。
HashMap 非線程安全歹篓,即任一時刻可以有多個線程同時寫 HashMap,可能會導 致數(shù)據(jù)的不一致揉阎。如果需要滿足線程安全庄撮,可以用 Collections 的 synchronizedMap 方法使 HashMap 具有線程安全的能力,或者使用 ConcurrentHashMap毙籽。
ConcurrentHashMap取消了Segment分段鎖洞斯,采用CAS和synchronized來保證并發(fā)安全。數(shù)據(jù)結(jié)構(gòu)跟HashMap1.8的結(jié)構(gòu)類似坑赡,數(shù)組+鏈表/紅黑二叉樹烙如。synchronized只鎖定當前鏈表或紅黑二叉樹的首節(jié)點么抗,這樣只要hash不沖突,就不會產(chǎn)生并發(fā)厅翔,效率又提升N倍乖坠。
抽象方法需要子類重寫,而靜態(tài)的方法是無法被重寫的刀闷,因此二者是矛盾的熊泵。synchronized和方法的實現(xiàn)細節(jié)有關(guān),抽象方法不涉及實現(xiàn)細節(jié)甸昏,因此也是相互矛盾的顽分。
類型擦除:如在代碼中定義的 List<Object>和 List<String>等類型,在編譯之后 都會變成List施蜜。JVM看到的只是List卒蘸,而由泛型附加的類型信息對JVM來說是不可見的。
BigDecimal和0比較
用num.compareTo(BigDecimal.ZERO)
不要用BigDecimal.ZERO.equals(null)//認為0和0.00不等
動態(tài)代理一般在代理類中做些額外的操作翻默。比如代理買房缸沃,還可能額外進行看房,貸款等操作修械。
vo中日期類型和decimal類型趾牧,統(tǒng)一定義為String類型。
原因:
用jackson A序列化和B反序列化日期時可能有會時區(qū)問題肯污。
decimal可能有會精度丟失問題翘单。
常見的引用類型:類類型,接口類型和數(shù)組蹦渣。
類類型:String
接口interface:List 接口哄芜,Map<K,V>
數(shù)組:int data[] = new int[3];
流與集合的異同:
- 集合的主要功能是以一定的時間和空間復雜度存儲和訪問元素,而流主要是用于元素計算
- 集合中的元素可以隨意添加和刪除柬唯,而流不能添加和刪除元素
- 流的元素是按需計算的认臊,只有當用到時他才會參與計算,而集合中的元素必須提前全都準備好
- 流只能遍歷一次,下面的代碼會報錯 java.lang.IllegalStateException: stream has already been operated upon or closed 流已經(jīng)被消費掉
List<String> names = Arrays.asList("Java8", "Lambdas", "In", "Action");
Stream<String> s = names.stream();
s.forEach(System.out::println);
s.forEach(System.out::println);
- 集合采用外部迭代锄奢,流采用內(nèi)部迭代美尸。內(nèi)部迭代意味著 Java 可以替你選擇更優(yōu)的迭代策略和并行處理。而外部迭代如果程序員想著做個更優(yōu)的迭代/采用并行就相當于“下次一定”了
Stream和parallelStream