c=newComparator(){publicintcompare(Integeri1,Integeri2){returni1-i2;//升序}};Listl=newArrayList();l.add(newInteger(-2000000000));l.add(newInteger(2000000000));Collec" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

java解惑你知多少(三)

系統 2223 0

17.?不要使用基于減法的比較器

Java代碼 ? ? 收藏代碼
  1. Comparator<Integer>?c?=? new ?Comparator<Integer>()?{??
  2. ? public ? int ?compare(Integer?i1,?Integer?i2)?{??
  3. ?? return ?i1?-?i2; //?升序 ??
  4. ?}??
  5. };??
  6. List<Integer>?l?=? new ?ArrayList<Integer>();??
  7. l.add( new ?Integer(- 2000000000 ));??
  8. l.add( new ?Integer( 2000000000 ));??
  9. Collections.sort(l,?c);??
  10. System.out.println(l); //?[2000000000,?-2000000000] ??

上面程序的比較器是升序,結果卻不是這樣,比較時出現了什么問題?

?

先看看下面程序片斷:

Java代碼 ? ? 收藏代碼
  1. int ?x?=?- 2000000000 ;??
  2. int ?y?=? 2000000000 ;??
  3. /* ?
  4. ?*?-2000000000?即?-(01110111001101011001010000000000) ?
  5. ?*?的補碼為:????????????????10001000110010100110110000000000 ?
  6. ?*? ?
  7. ?*?計算過程使用豎式表示: ?
  8. ?*?10001000110010100110110000000000 ?
  9. ?*?10001000110010100110110000000000 ?
  10. ?*?-------------------------------- ?
  11. ?*?00010001100101001101100000000000 ?
  12. ?*? ?
  13. ?*?計算結果溢出,結果為294967296 ?
  14. ?*/ ??
  15. System.out.println(x?-?y); //?294967296 ??

所以不要使用減法的比較器,除非能確保要比較的數值之間的距離永遠不會大于Intger. MAX_VALUE。

?

基于整型的比較器的實現一般使用如下的方式來比較:

Java代碼 ? ? 收藏代碼
  1. public ? int ?compare(Integer?i1,?Integer?i2)?{??
  2. ? return ?(i1?<?i2???- 1 ?:?(i1?==?i2??? 0 ?:? 1 ));??
  3. }??

?
18.? int i=-2147483648與int i=-(2147483648)?

Java代碼 ? ? 收藏代碼
  1. int ?i=-( 2147483648 );??

編譯通不過!為什么

?

int字面常量2147483638只能作為一元負操作符的操作數來使用。

?

類似的還有最大long:

Java代碼 ? ? 收藏代碼
  1. long ?i=–(9223372036854775808L);??

?
字符串

19.?char類型相加

Java代碼 ? ? 收藏代碼
  1. System.out.println( 'a' ?+? 'A' ); //162 ??

上面的結果不是 aA ,而是 162。


當且僅當+操作符的操作數中至少有一個是String類型時,才會執行字符串連接操作;否則,執行加法。如果要連接的

數值沒有一個是字符串類型的,那么你可以有幾種選擇:預置一個空字符串("" + 'a' + 'A');將第一個數值用

String.valueOf()顯示地轉換成一個字符串(String.valueOf('a') + 'A');使用一個字符串緩沖區(sb.append

('a');sb.append('A'););或者如果使用的是JDK5.0,可以用printf(System.out.printf("%c%c",'a','A'));


20.?程序中的Unicode轉義字符

Java代碼 ? ? 收藏代碼
  1. //\u0022是雙引號的Unicode編碼表示 ??
  2. System.out.println( "a\u0022.length()?+?\u0022b" .length()); //?2 ??

Unicode編碼表示的字符是在編譯期間就轉換成了普通字符,它與普通轉義字符(如:\")是不一樣的,它們是在程序

被解析為各種符號之后才處理轉義字符序列。

?

21.?注釋中的Unicode轉義字符

如果程序中含有以下的注釋:// d:\a\b\util ,程序將不能編譯通過,原因是\u后面跟的不是四個十六進制數字,但

編譯器在編譯時卻要把\u開頭的字符的字符看作是Unicode編碼表示的字符。

?

所以要注意:注釋中也是支持Unicode轉義字符的。

?

另外一個問題是不能在注釋行的中間含有 \u000A 表示換行的Unicode字符,因為這樣在編譯時讀到 \u000A 時,表示

行結束,那么后面的字符就會當作程序代碼而不在是注釋了。


22.?Windows與Linux上的行結束標示符

Java代碼 ? ? 收藏代碼
  1. String?line?=?(String)System.getProperties().get( "line.separator" );??
  2. for ( int ?i?= 0 ;?i?<?line.length();i++){??
  3. ?System.out.println(( int )line.charAt(i));??
  4. }??

在Windows上運行結果:
13
10

在Linux上運行的結果:
10

在Windows平臺上,行分隔符是由回車(\r)和緊其后的換行(\n)組成,但在Unix平臺上通常使用單獨的換行(\n)

表示。


23.?輸出0-255之間的ISO8859-1符

Java代碼 ? ? 收藏代碼
  1. byte ?bts[]?=? new ? byte [ 256 ];??
  2. for ?( int ?i?=? 0 ;?i?<? 256 ;?i++)?{??
  3. ?bts[i]?=?( byte )?i;??
  4. }??
  5. //?String?str?=?new?String(bts,"ISO8859-1");//正確的做法 ??
  6. String?str?=? new ?String(bts); //使用操作系統默認編碼方式編碼(XP?GBK) ??
  7. for ?( int ?i?=? 0 ,?n?=?str.length();?i?<?n;?i++)?{??
  8. ?System.out.print(( int )?str.charAt(i)?+? "?" );??
  9. }??

上面不會輸出0-255之間的數字串,正確的方式要使用new String(bts," ISO8859-1") 方式來解碼。

?

ISO8859-1是唯一能夠讓該程序按順序打印從0到255的整數的缺少字符集,這也是唯一在字符和字節之間一對一的映射

字符集。

?

通過java獲取操作系統的默認編碼方式:

Java代碼 ? ? 收藏代碼
  1. System.getProperty( "file.encoding" ); //jdk1.4或之前版本 ??
  2. java.nio.charset.Charset.defaultCharset(); //jdk1.5或之后版本 ??

?
24.?String的replace()與replaceAll()

Java代碼 ? ? 收藏代碼
  1. System.out.println( "." .replaceAll( ".class" ,? "\\$" ));??

上面程序將 . 替換成 \$,但運行時報異常,主要原replaceAll的第二參數有兩個字符(\ $)是特殊字符,具有特殊

意思(\用來轉移 \ 與 $,$后面接數字表示反向引用)。另外,replaceAll的第一參數是正則表達式,所以要注意特

殊字符,正確的作法有以下三種:

Java代碼 ? ? 收藏代碼
  1. System.out.println( ".class" .replaceAll( "\\." ,? "\\\\\\$" ));??
  2. System.out.println( ".class" .replaceAll( "\\Q.\\E" ,? "\\\\\\$" ));??
  3. System.out.println( ".class" .replaceAll(Pattern.quote( "." ),?Matcher.quoteReplacement( "\\$" )));??

API對\、\Q與\E的解釋: ?
\? 引用(轉義)下一個字符 ?
\Q引用所有字符,直到 \E ?
\E結束從 \Q 開始的引用

?

JDK5.0新增了一些解決此問題的新方法:
java.util.regex.Pattern.quote(String s):使用\Q與\E將參數引起來,這些被引用的字符串就是一般的字符,哪怕

含有正則式特殊字符。
java.util.regex.Matcher.quoteReplacement(String s):將\與$轉換成能應用于replaceAll第二個參數的字符串,

即可作為替換內容。

String的replace(char oldChar, char newChar)方法卻不使用正則式,但它們只支持字符,而不是字符串,使用起來

受限制:

Java代碼 ? ? 收藏代碼
  1. System.out.println( "." .replace( '.' , '\\' )); //能將?.?替換成?\ ??
  2. System.out.println( "." .replace( '.' , '$' ));? //能將?.?替換成?$ ??

?
25.?一段程序的三個Bug

Java代碼 ? ? 收藏代碼
  1. Random?rnd?=? new ?Random();??
  2. StringBuffer?word?=? null ;??
  3. switch ?(rnd.nextInt( 2 ))?{??
  4. case ? 1 :??
  5. ?word?=? new ?StringBuffer( 'P' );??
  6. case ? 2 :??
  7. ?word?=? new ?StringBuffer( 'G' );??
  8. default :??
  9. ?word?=? new ?StringBuffer( 'M' );??
  10. }??
  11. word.append( 'a' );??
  12. word.append( 'i' );??
  13. word.append( 'n' );??
  14. System.out.println(word);??

上面的程序目的是等概率的打印 Pain、Gain、Main 三個單詞,但多次運行程序卻發現永遠只會打印 ain,這是為什

么?

?

第一個問題在于:rnd.nextInt(2)只會返回0、1 兩個數字,所以上面只會走case 1: 的分支語句,case 2: 按理是永

遠不會走的。

第二個問題在于:如果case語句不以break結束時,則一直會往向運行,即直到執行到break的case語句止,所以上面

的的語句每次都會執行default分支語句。

第三個問題在于:StringBuffer的構造函數有兩種可接受參數的,一個是StringBuffer(int capacity)、另一個是

StringBuffer(String str),上面用的是StringBuffer(char)構造函數,實質上運行時將字符型轉換成了int型,這樣

將字符當作StringBuffer的初始容量了,而不是字符本身。

?

以下是修改后的程序片段:

Java代碼 ? ? 收藏代碼
  1. Random?rnd?=? new ?Random();??
  2. StringBuffer?word?=? null ;??
  3. switch ?(rnd.nextInt( 3 ))?{??
  4. case ? 1 :??
  5. ?word?=? new ?StringBuffer( "P" );??
  6. ? break ;??
  7. case ? 2 :??
  8. ?word?=? new ?StringBuffer( "G" );??
  9. ? break ;??
  10. default :??
  11. ?word?=? new ?StringBuffer( "M" );??
  12. ? break ; //?可以不要 ??
  13. ??
  14. }??
  15. word.append( 'a' );??
  16. word.append( 'i' );??
  17. word.append( 'n' );??
  18. System.out.println(word);??

java解惑你知多少(三)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲免费视频在线观看 | 欧美日韩一区在线观看 | 成 人 免费 黄 色 视频 | 四虎在线播放免费永久视频 | 日本不卡在线观看 | 四虎www免费人成 | 一级成人毛片免费观看 | 91青青青青青爽在线 | 国产三级久久久精品麻豆三级 | 四虎影院永久 | 久久久久香蕉视频 | 日日夜夜天天久久 | 老子影院午夜伦手机在线看 | 99热久久这里只有精品6国产网 | 日韩天堂 | 国产爱久久久精品 | 亚洲国产成人精品91久久久 | 韩国欧美一级毛片免费 | 久久精品夜色国产 | 色综合色狠狠天天综合色 | 欧美色操 | 国产一区二区三区不卡观 | 免费a一级毛片在线播放 | 日韩综合图区 | 欧美视频www | 一区二区三区亚洲视频 | 老司机免费福利视频无毒午夜 | 久久综合视频网站 | 999国产精品999久久久久久 | 97影院3 | 九九视频免费精品视频免费 | 四虎网址换成什么了2021 | 色女人久久 | 热久久国产欧美一区二区精品 | 亚洲网视频| 国产最新一区二区三区天堂 | 国产精品视频免费视频 | 亚洲精品色一区色二区色三区 | 成人国产片免费 | 国产精品久久久香蕉 | 日本在线视频毛片 |