【Java】第一阶段练习题
字符串
如果字符串常量池中存在相同內(nèi)容的字符串對象的引用,則將這個(gè)引用返回。否則新的字符串對象被創(chuàng)建,然后將這個(gè)引用放入字符串常量池,并返回該引用。
第三段s1和s2都是以字面量的形式創(chuàng)建,s1首先創(chuàng)建,s2創(chuàng)建的時(shí)候會(huì)在常量池中找是否相同內(nèi)容的字符串對象,找到了s1,把s1的引用返回給s2。所以s1和s2的地址是相同的。
凡是String s=“a”+“b”;或者String s=“ab”;產(chǎn)生一個(gè)字符串常量在棧中。
第四段【s1+“c”】是調(diào)用stringBuffer操作并創(chuàng)建一個(gè)String對象也就是說+操作符使用StringBuffer的append方式實(shí)現(xiàn)的最后返回一個(gè)新創(chuàng)建的String對象,而不是string常量。String s3=s1+“c”;保存在堆中。
凡是字符串變量與字符串變量或者字符串常量之間使用+都會(huì)產(chǎn)生一個(gè)String對象到堆中。
String類的對象內(nèi)容不可改變,所以每當(dāng)進(jìn)行字符串拼接時(shí),總是會(huì)在內(nèi)存中創(chuàng)建一個(gè)新的對象,所以經(jīng)常改變內(nèi)容的字符串最好不要用String,因?yàn)槊看紊蓪ο蠖紩?huì)對系統(tǒng)性能產(chǎn)生影響。
StringBuilder又稱為可變字符序列,是JDK5.0中新增加的一個(gè)類,它是一個(gè)類似于String的字符串緩沖區(qū),通過某些方法調(diào)用可以改變該序列的長度和內(nèi)容。即它是一個(gè)容器,容器中可以裝很多字符串,并且能夠?qū)ζ渲械淖址M(jìn)行各種操作。它的內(nèi)部擁有一個(gè)數(shù)組用來存放字符串內(nèi)容,進(jìn)行字符串拼接時(shí),直接在數(shù)組中加入新內(nèi)容,StringBuilder會(huì)自動(dòng)維護(hù)數(shù)組的擴(kuò)容。
日期
public static void main(String[] args) throws ParseException {//獲取當(dāng)前的日期,并把這個(gè)日期轉(zhuǎn)換為指定格式的字符串,如2088-08-08 08:08:08。Date d1 = new Date();SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String formatDate1 = sdf1.format(d1);System.out.println(formatDate1);//使用SimpleDateFormat類,把2018-03-04轉(zhuǎn)換為2018年03月04日。SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");Date d2 = sdf2.parse("2018-03-04");SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy年MM月dd日");String formatDate2 = sdf3.format(d2);System.out.println(formatDate2);//用程序判斷2018年2月14日是星期幾Calendar c = Calendar.getInstance();c.set(2018,2,14);int week = c.get(Calendar.DAY_OF_WEEK);System.out.println(week);System.out.println(c.get(Calendar.YEAR)+"年"+c.get(Calendar.MONTH)+"月"+c.get(Calendar.DATE)+"日是星期"+(week-1));}集合
集合框架:
list轉(zhuǎn)為數(shù)組,可以調(diào)用toArray方法
public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);Object[] o = list.toArray();System.out.println(Arrays.toString(o));}迭代器的實(shí)現(xiàn)原理
Iterator it = list.iterator();
首先調(diào)用iterator方法獲得一個(gè)迭代器對象。然后用hasNext方法判斷是否還有下一個(gè)元素,用Next方法獲取下一個(gè)元素。
迭代器在遍歷集合的時(shí)候,內(nèi)部采用指針來跟蹤集合中的元素。在調(diào)用Next之前,指針指在第一個(gè)元素之前,不指向任何元素。每調(diào)用一個(gè)Next,指針后移一位,并將當(dāng)前指向元素返回。直到遇到hasNext返回false結(jié)果時(shí)停止移動(dòng)指針。
Comparable和Comparator兩個(gè)接口的區(qū)別
Comparable:強(qiáng)行對實(shí)現(xiàn)它的每個(gè)類的對象進(jìn)行整體排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為它的自然比較方法。只能在類中實(shí)現(xiàn)compareTo()一次,不能經(jīng)常修改類的代碼實(shí)現(xiàn)自己想要的排序。實(shí)現(xiàn)此接口的對象列表(和數(shù)組)可以通過Collections.sort(和Arrays.sort)進(jìn)行自動(dòng)排序,對象可以用作有序映射中的鍵或有序集合中的元素,無需指定比較器。
Comparator強(qiáng)行對某個(gè)對象進(jìn)行整體排序。可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實(shí)現(xiàn)精確控制。還可以使用Comparator來控制某些數(shù)據(jù)結(jié)構(gòu)(如有序set或有序映射)的順序,或者為那些沒有自然順序的對象collection提供排序。
異常
異常的繼承體系
throw與throws的區(qū)別
異常處理方式
try-catch-finally:自己定義異常的處理邏輯,處理之后的程序可以繼續(xù)運(yùn)行。try是可能發(fā)生異常的部分,catch寫明異常的處理邏輯,finally代碼塊是無論是否發(fā)生異常,都必須執(zhí)行的代碼,用于釋放資源。
throws:在方法聲明處寫上異常類,拋出給調(diào)用者進(jìn)行處理,最后由JVM進(jìn)行中斷處理。
常見異常和出現(xiàn)原因
- 空指針異常:當(dāng)應(yīng)用試圖在要求使用對象的地方使用了null時(shí),拋出該異常。
- 數(shù)組越界異常:當(dāng)對數(shù)組的索引值為負(fù)數(shù)或大于等于數(shù)組大小時(shí)拋出此異常。
- 算數(shù)運(yùn)算異常:除零操作
- 數(shù)字格式異常:當(dāng)試圖將一個(gè)String轉(zhuǎn)換為指定的數(shù)字類型,而該字符串并不滿足數(shù)字類型要求的格式時(shí),拋出該異常。
并發(fā)和并行的區(qū)別
并行:指兩個(gè)或多個(gè)事件在同一時(shí)刻發(fā)生(同時(shí)發(fā)生)。
并發(fā):指兩個(gè)或多個(gè)事件在同一個(gè)時(shí)間段內(nèi)發(fā)生。(不同時(shí))
進(jìn)程和線程的區(qū)別
進(jìn)程指正在運(yùn)行的程序。確切的來說,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行,即變成一個(gè)進(jìn)程,進(jìn)程是處于運(yùn)行過程中的程序,并且具有一定獨(dú)立功能。
線程是進(jìn)程中的一個(gè)執(zhí)行單元,負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行,一個(gè)進(jìn)程中至少有一個(gè)線程。一個(gè)進(jìn)程中是可以有多個(gè)線程的,這個(gè)應(yīng)用程序也可以稱之為多線程程序。
一個(gè)程序運(yùn)行后至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程中可以包含多個(gè)線程,但一個(gè)進(jìn)程中至少包含一個(gè)線程。比如使用迅雷軟件下載網(wǎng)絡(luò)文件時(shí),同時(shí)下載多個(gè)文件,就使用到了多線程下載。
自定義異常
public class NoScoreExcpetion extends Exception {public NoScoreExcpetion() {}public NoScoreExcpetion(String message) {super(message);} } public class Student {private String name;private int id;private int score; ...... //其他方法省略 ......public void setScore(int score) throws NoScoreExcpetion {if(score <= 0){throw new NoScoreExcpetion("成績必須大0");}this.score = score;} } public class Test {public static void main(String[] args) throws NoScoreExcpetion {Student s1 = new Student();s1.setName("張三");s1.setId(1);s1.setScore(-100);System.out.println(s1);} }多線程
創(chuàng)建多線程對象,開啟多線程。
在子線程中輸出1-100之間的偶數(shù),主線程輸出1-100之間的奇數(shù)。
start()方法與run()方法的區(qū)別
start開啟線程,讓jvm調(diào)用run()方法在開啟的線程中執(zhí)行。
run不開啟線程,只是對象調(diào)用方法
創(chuàng)建線程的兩種方式
繼承Thread:定義線程子類,繼承Tread,重寫run方法。創(chuàng)建線程子類對象,調(diào)用start方法開啟線程。
實(shí)現(xiàn)Runnable:實(shí)現(xiàn)Runnable類,并重寫run方法。創(chuàng)建Runnable實(shí)現(xiàn)類對象,傳入Thread對象的含參構(gòu)造方法中,通過Thread對象調(diào)用start方法開啟線程。
public class Test{public static void main(String[] args) {Runnable r = new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}};Thread t = new Thread(r);t.start();System.out.println(Thread.currentThread().getName());} }實(shí)現(xiàn)Runnable接口的優(yōu)勢
- 接口可以多實(shí)現(xiàn),而類只能單繼承
- 適合多個(gè)相同的程序代碼的線程去共享同一個(gè)資源。
- 增加程序的健壯性,實(shí)現(xiàn)解耦操作,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)立。
- 線程池只能放入實(shí)現(xiàn)Runnable或callable類線程,不能直接放入繼承Thread的類。
線程狀態(tài)
- new:新建狀態(tài)
- blocked:阻塞狀態(tài)。當(dāng)一個(gè)線程試圖獲取一個(gè)對象鎖,而該對象鎖被其他的線程持有,則該線程進(jìn)入Blocked狀態(tài);當(dāng)該線程持有鎖時(shí),該線程將變成Runnable狀態(tài)。
- time-waiting:休眠狀態(tài)。一個(gè)線程在等待另一個(gè)線程執(zhí)行一個(gè)(喚醒)動(dòng)作時(shí),該線程進(jìn)入Waiting狀態(tài)。進(jìn)入這個(gè)狀態(tài)后是不能自動(dòng)喚醒的,必須等待另一個(gè)線程調(diào)用notify或者notifyAll方法才能夠喚醒。
- waiting:無限等待 。同waiting狀態(tài),有幾個(gè)方法有超時(shí)參數(shù),調(diào)用他們將進(jìn)入Timed Waiting狀態(tài)。這一狀態(tài)將一直保持到超時(shí)期滿或者接收到喚醒通知。帶有超時(shí)參數(shù)的常用方法有Thread.sleep 、Object.wait。
- runnable:運(yùn)行狀態(tài)
- terminate:終止?fàn)顟B(tài)
線程池:是一個(gè)容納多個(gè)線程的容器,里面的線程可以反復(fù)拿出來使用,無需反復(fù)創(chuàng)建線程對象,而過多消耗系統(tǒng)資源。
線程池的優(yōu)點(diǎn):
- 降低資源消耗:減少創(chuàng)建和銷毀線程的次數(shù),可以反復(fù)利用線程。
- 提高線程的可管理性:可以根據(jù)系統(tǒng)的承受能力,調(diào)整線程池中工作線程數(shù)目,防止因?yàn)橄倪^多的內(nèi)存,而把服務(wù)器累趴下(每個(gè)線程需要大約1MB內(nèi)存,線程開的越多,消耗的內(nèi)存也就越大,最后死機(jī))。
- 提高響應(yīng)速度:不需要?jiǎng)?chuàng)建線程就可以執(zhí)行任務(wù)。
重寫和重載
重寫是子類對父類的允許訪問的方法的實(shí)現(xiàn)過程進(jìn)行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫!
重載是在一個(gè)類里面,方法名字相同,而參數(shù)不同。返回類型可以相同也可以不同。每個(gè)重載的方法(或者構(gòu)造函數(shù))都必須有一個(gè)獨(dú)一無二的參數(shù)類型列表。
下面的代碼編譯會(huì)報(bào)錯(cuò),因?yàn)闆]有重寫run方法,run里有參數(shù),不是重寫!
public class Test07 implements Runnable {public static void main(String[] args) {Thread t = new Thread(new Test07());t.start();}public void run(int num) {for (int i = 0; i < num; i++) {System.out.println(i);}} }Lambda
省略規(guī)則
- ()內(nèi)的參數(shù)類型可以省略
- ()內(nèi)如果只有一個(gè)參數(shù),()可省略
- {}內(nèi)如果只有一個(gè)語句可以省略{}、return和分號(hào)
格式
- ():參數(shù)列表
- ->:指向動(dòng)作
- {}:方法體括號(hào)
使用前提
- 必須有接口,且抽象方法唯一。
- 必須可推斷,方法的參數(shù)或局部變量類型必須為Lambda對應(yīng)的接口類型,才能使用Lambda作為該接口的實(shí)例。
無參無返回值Lambda練習(xí)
給定一個(gè)導(dǎo)演 Director接口,內(nèi)含唯一的抽象方法makeMovie,且無參數(shù)、無返回值,使用lambda表達(dá)式在Test中完成調(diào)用。
有參有返回值Lambda練習(xí)
給定一個(gè)計(jì)算器 Calculator 接口,內(nèi)含抽象方法 calc (減法),其功能是可以將兩個(gè)數(shù)字進(jìn)行相減,并返回差值。使用Lambda表達(dá)式在Test中完成調(diào)用。
總結(jié)
以上是生活随笔為你收集整理的【Java】第一阶段练习题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里-2019算法岗笔试编程题-kmp匹
- 下一篇: 【Java】StringBuilder类