沈陽市建設(shè)工程項目管理中心網(wǎng)站優(yōu)化大師官網(wǎng)
Java編程問題top100---基礎(chǔ)語法系列一
- 一、Java += 操作符實質(zhì)
- 二、將InputStream轉(zhuǎn)換為String
- 使用IOUtils
- 自己寫輪子
- 三、將數(shù)組轉(zhuǎn)換為List
- 四、如何遍歷map對象
- 使用For-Each迭代entries(方法一)
- 使用For-Each迭代keys和values(方法二)
- 使用Iterator迭代(方法三)
- 使用泛型
- 不使用泛型
- 迭代keys并搜索values(低效的)(方法四)
- 總結(jié)
- 五、public,protected,private,不加修飾符。有什么區(qū)別呢?
- Java編程問題top100---基礎(chǔ)語法系列導(dǎo)航
記得這個是當時剛?cè)雽W那會嘗試去看的一個github上的優(yōu)秀內(nèi)容,當時很多東西看得云里霧里,不太懂。
現(xiàn)在正好有空了,再來一次,會稍作修改再加上代碼實踐,有問題可以留言。
重溫的同時,希望對你能有所幫助。
以下系列將會是對stackoverflow上Java相關(guān)、投票數(shù)TOP100的問答(精修版)。
一、Java += 操作符實質(zhì)
問題:我之前以為:
i += j 等同于 i = i + j;
但假設(shè)有:
int i = 5; long j = 8;
這時 i = i + j 不能編譯,但 i += j 卻可以編譯。這說明兩者還是有差別的
這是否意味著,i += j,實際是等同于 i= (type of i) (i + j)呢?
// Java += 操作符實質(zhì)
public class test01 {public static void main(String[] args) {int i = 5;long j = 8;// i = i + j;// 編譯報錯,需要的類型int,提供了longi += j; // 這行沒有問題i = i + (int) j; // 這行也沒問題}
}
回答
對復(fù)合賦值表達式E1 op= E2
來說, (諸如 i += j
i -= j
i*=j
i/=j
等等),其實是等同于 E1 = (T)((E1) op (E2))
,
其中,E1和E2表示兩個操作數(shù),T是E1
這個元素的類型。
舉例來說,如下的代碼
int i = 5;long j = 8;
i += j;
等同于i = (int)(i + j);
也就是(i + j)
先執(zhí)行,然后(i + j)的結(jié)果
強制類型轉(zhuǎn)換為int類型
新人注意:表達式i = (int)(i + j);
里(i + j)
這個是帶括號的。
它也等價于i = i + (int) j;
二、將InputStream轉(zhuǎn)換為String
首先項目名字那按右鍵選Add Framework Support
或者選添加框架支持
,然后選Maven
,在pom.xml
里寫入下面這個
<dependencies><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency></dependencies>
使用IOUtils
最靠譜的方法,用Apache commons IOUtils
文檔test02.txt
ABC a b ABc b
你好
//將InputStream轉(zhuǎn)換為String
public class test02 {public static void main(String[] args) throws Exception {FileInputStream inputStream = new FileInputStream("D:\test02.txt");String encoding = "UTF-8";StringWriter writer = new StringWriter();IOUtils.copy(inputStream, writer, encoding);String theString = writer.toString();// String theString = IOUtils.toString(inputStream, encoding);// 這個方法其實封裝了上面的方法,減少了一個參數(shù)}
}
或者
String theString = IOUtils.toString(inputStream, encoding);
//這個方法其實封裝了上面的方法,減少了一個參數(shù)
自己寫輪子
如果不想引入Apache庫,也可以這樣做
//將InputStream轉(zhuǎn)換為String
public class test02 {static String convertStreamToString(InputStream is) {Scanner s = new Scanner(is).useDelimiter("你好");//讀取到你好這個詞就會停止輸入return s.hasNext() ? s.next() : "";}public static void main(String[] args) throws FileNotFoundException {FileInputStream fileInputStream = new FileInputStream("test.txt");System.out.println(convertStreamToString(fileInputStream));}
}
三、將數(shù)組轉(zhuǎn)換為List
1、最簡單的for循環(huán)遍歷挨個賦值給List。
2、Arrays.asList(array);
// 將數(shù)組轉(zhuǎn)換為List
public class test03 {public static void main(String[] args) {Integer[] array = {1, 2, 3, 4};List<Integer> arrayLists = Arrays.asList(array);// 這里System.out.println(arrayLists);}
}
但這樣做會有坑:
- 生成的list,是固定長度的。也就是說,如果調(diào)用它的
add()
方法或者remove()
方法,都會拋異常UnsupportedOperationException。 - 如果修改
數(shù)組
的值,list
中的對應(yīng)值也會改變!
因為Arrays.asList() 返回的是Arrays里的內(nèi)部靜態(tài)類
,而不是Java.util.ArrayList這個類。
這個java.util.Arrays.ArrayList有set(),get(),contains()方法,但是沒有任何add()
方法,所以它是固定大小的.
建議用這個
Collections.addAll(arrayLists, array);
// 將數(shù)組轉(zhuǎn)換為List
public class test03 {public static void main(String[] args) {Integer[] array = {1, 2, 3, 4};List<Integer> arrayLists = new ArrayList<>();Collections.addAll(arrayLists, array);// 這里}
}
四、如何遍歷map對象
在Java中有多種遍歷HashMap的方法。
讓我們回顧一下最常見的方法和它們各自的優(yōu)缺點。
由于所有的Map都實現(xiàn)了Map接口,所以接下來方法適用于所有Map(如:HaspMap,TreeMap,LinkedMap,HashTable,ConcurrentHashMAp,……)
使用For-Each迭代entries(方法一)
這是最常見的方法,并在大多數(shù)情況下更可取的。當你在循環(huán)中需要使用Map的鍵和值時,就可以使用這個方法
public class test04 {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();// map = null;map.put("a", 1);testOne(map);}public static void testOne(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());}}else {System.out.println(map);}}
}
注意:遍歷之前你應(yīng)該判斷是否為空引用。如果遍歷的map是null的話,For-Each循環(huán)會拋出NullPointerException異常。
使用For-Each迭代keys和values(方法二)
如果你只需要用到map的keys或values時,你可以遍歷KeySet或者values代替entrySet
public static void testTwo(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (String key : map.keySet()) {System.out.println("Key = " + key);}for (Integer value : map.values()) {System.out.println("Value = " + value);}}}
這個方法比entrySet迭代具有輕微的性能優(yōu)勢(大約快10%)并且代碼更簡潔
使用Iterator迭代(方法三)
使用泛型
public static void testThree(Map<String, Integer> map) {Iterator<Map.Entry<String, Integer>> entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry<String, Integer> entry = entries.next();System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}}
不使用泛型
public static void testFour(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {Iterator entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry entry = (Map.Entry) entries.next();String key = (String) entry.getKey();Integer value = (Integer) entry.getValue();System.out.println("Key = " + key + ", Value = " + value);}} else {System.out.println(map);}}
你可以使用同樣的技術(shù)迭代keyset或者values
首先,它是遍歷java 5 以前版本的map的唯一方法。
第二是可以讓你在迭代的時候從map中刪除entries的(通過調(diào)用iterator.remover())唯一方法。
如果你試圖在For-Each迭代的時候刪除entries,你將會得到unpredictable resultes 異常。
從性能方面看,這個方法等價于使用For-Each迭代(方法二)
迭代keys并搜索values(低效的)(方法四)
public static void testFive(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (String key : map.keySet()) {Integer value = map.get(key);System.out.println("Key = " + key + ", Value = " + value);}} else {System.out.println(map);}}
比方法一更簡潔,但是實際更慢更低效,通過key得到value值更耗時
總結(jié)
如果你只需要使用key或者value使用方法二使用For-Each迭代keys和values
,如果你使用java 5 以前的版本或者打算在迭代的時候移除entries,使用方法三使用Iterator迭代
。其他情況請使用方法一For-Each迭代entries
方法。避免使用迭代keys并搜索values(低效的)
方法。
五、public,protected,private,不加修飾符。有什么區(qū)別呢?
如下表所示,Y表示能訪問(可見性),N表示不能訪問,例如第一行的第3個Y,表示類的變量/方法如果是用public修飾,它的子類能訪問這個變量/方法
修飾符 | 類內(nèi)部 | 同個包(package) | 子類 | 其他范圍 |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
無修飾符 | Y | Y | N or Y(見說明) | N |
private | Y | N | N | N |
說明:
需要特別說明“無修飾符”這個情況,子類能否訪問父類中無修飾符的變量/方法,取決于子類是否在同一個包中。如果子類和父類在同一個包中,那么子類可以訪問父類中的無修飾符的變量/方法,否則不行。
Java編程問題top100—基礎(chǔ)語法系列導(dǎo)航
Java編程問題top100—基礎(chǔ)語法系列(一)
Java編程問題top100—基礎(chǔ)語法系列(二) 待更新
Java編程問題top100—基礎(chǔ)語法系列(三) 待更新
如有錯誤,還請多多指教!
轉(zhuǎn)載或者引用本文內(nèi)容請注明來源及原作者:橘足輕重;