學Java必看:Java最常用方法總結(ImportNew年度好文)

來源:互聯網
上載者:User

在Java編程中,有些知識 並不能僅通過語言規範或者標準API文檔就能學到的。在本文中,我會盡量收集一些最常用的習慣用法,特別是很難猜到的用法。(Joshua Bloch的《Effective Java》對這個話題給出了更詳盡的論述,可以從這本書裡學習更多的用法。)

我把本文的所有代碼都放在公用場所裡。你可以根據自己的喜好去複製和修改任意的程式碼片段,不需要任何的憑證。 目錄 實現: equals() hashCode() compareTo() clone() 應用: StringBuilder/StringBuffer Random.nextInt(int) Iterator.remove() StringBuilder.reverse() Thread/Runnable try-finally 輸入/輸出: 從輸入資料流裡讀取位元組資料 從輸入資料流裡讀取塊資料 從檔案裡讀取文本 向檔案裡寫文本 預防性檢測: 數值 對象 數組索引 數組區間 數組: 填充元素 複製一個範圍內的數組元素 調整數組大小 封裝 個位元組封裝成一個int 分解成4個位元組

實現equals()

class Person {  String name;  int birthYear;  byte[] raw;   public boolean equals(Object obj) {    if(!obj instanceofPerson)      return false;     Person other = (Person)obj;    return name.equals(other.name)        && birthYear == other.birthYear        && Arrays.equals(raw, other.raw);  }   public int hashCode() { ... }}
參數必須是Object類型,不能是外圍類。 foo.equals(null) 必須返回false,不能拋NullPointerException。(注意,null instanceof 任意類 總是返回false,因此上面的代碼可以運行。) 基本類型域(比如,int)的比較使用 == ,基本類型數組域的比較使用Arrays.equals()。 覆蓋equals()時,記得要相應地覆蓋 hashCode(),與 equals() 保持一致。 參考: java.lang.Object.equals(Object)。

實現hashCode()

class Person {  String a;  Object b;  bytec;  int[] d;   public int hashCode() {    return a.hashCode() + b.hashCode() + c + Arrays.hashCode(d);  }   public boolean equals(Object o) { ... }}

當x和y兩個對象具有x.equals(y) == true ,你必須要確保x.hashCode() == y.hashCode()。 根據逆反命題,如果x.hashCode() != y.hashCode(),那麼x.equals(y) == false 必定成立。 你不需要保證,當x.equals(y) == false時,x.hashCode() != y.hashCode()。但是,如果你可以儘可能地使它成立的話,這會提高雜湊表的效能。 hashCode()最簡單的合法實現就是簡單地return 0;雖然這個實現是正確的,但是這會導致HashMap這些資料結構運行得很慢。 參考:java.lang.Object.hashCode()。

實現compareTo()

class Person implementsComparable<Person> {  String firstName;  String lastName;  intbirthdate;   // Compare by firstName, break ties by lastName, finally break ties by birthdate  public int compareTo(Person other) {    if(firstName.compareTo(other.firstName) != 0)      returnfirstName.compareTo(other.firstName);    else if (lastName.compareTo(other.lastName) != 0)      returnlastName.compareTo(other.lastName);    else if (birthdate < other.birthdate)      return-1;    else if (birthdate > other.birthdate)      return1;    else      return0;  }}

總是實現泛型版本 Comparable 而不是實現原始類型 Comparable 。因為這樣可以節省代碼量和減少不必要的麻煩。 只關心返回結果的加號或減號(負/零/正),它們的大小不重要。 Comparator.compare()的實現與這個類似。 參考:java.lang.Comparable。

實現clone()

class Values implementsCloneable {  String abc;  doublefoo;  int[] bars;  Date hired;   public Values clone() {    try{      Values result = (Values)super.clone();      result.bars = result.bars.clone();      result.hired = result.hired.clone();      returnresult;    }catch(CloneNotSupportedException e) {  // Impossible      thrownew AssertionError(e);    }  }}
使用 super.clone() 讓Object類負責建立新的對象。 基本類型域都已經被正確地複製了。同樣,我們不需要去複製String和BigInteger等不可變類型。 手動對所有的非基本類型域(對象和數組)進行深度複製(deep copy)。 實現了Cloneable的類,clone()方法永遠不要拋CloneNotSupportedException。因此,需要捕獲這個異常並忽略它,或者使用不受檢異常(unchecked exception)封裝它。 不使用Object.clone()方法而是手動地實現clone()方法是可以的也是合法的。 參考:java.lang.Object.clone()、java.lang.Cloneable()。

使用StringBuilder或StringBuffer

// join(["a", "b", "c"]) -> "a and b and c"String join(List<String> strs) {  StringBuilder sb = newStringBuilder();  booleanfirst = true;  for(String s : strs) {    if(first) first = false;    elsesb.append(" and ");    sb.append(s);  }  returnsb.toString();}
不要像這樣使用重複的字串串連:s += item ,因為它的時間效率是O(n^2)。 使用StringBuilder或者StringBuffer時,可以使用append()方法添加文本和使用toString()方法去擷取串連起來的整個文本。 優先使用StringBuilder,因為它更快。StringBuffer的所有方法都是同步的,而你通常不需要同步的方法。 參考java.lang.StringBuilder、java.lang.StringBuffer。

產生一個範圍內的隨機整數

Random rand = newRandom(); // Between 1 and 6, inclusiveintdiceRoll() {  return rand.nextInt(6) + 1;}
總是使用Java API方法去產生一個整數範圍內的隨機數。 不要試圖去使用 Math.abs(rand.nextInt()) % n 這些不確定的用法,因為它的結果是有偏差的。此外,它的結果值有可能是負數,比如當rand.nextInt() == Integer.MIN_VALUE時就會如此。 參考:java.util.Random.nextInt(int)。

使用Iterator.remove()

void filter(List<String> list) {  for(Iterator<String> iter = list.iterator(); iter.hasNext(); ) {    String item = iter.next();    if(...)      iter.remove();  }}
remove()方法作用在next()方法最近返回的條目上。每個條目只能使用一次remove()方法。 參考:java.util.Iterator.remove()。

返轉字串

String reverse(String s) {  return new StringBuilder(s).reverse().toString();}
這個方法可能應該加入Java標準庫。 參考:java.lang.StringBuilder.reverse()。

啟動一條線程

下面的三個例子使用了不同的方式完成了同樣的事情。

實現Runnnable的方式:

void startAThread0() {  new Thread(newMyRunnable()).start();} class MyRunnable implementsRunnable {  public void run() {    ...  }}

繼承Thread的方式:

void startAThread1() {  new MyThread().start();} class MyThread extendsThread {  public void run() {    ...  }}

匿名繼承Thread的方式:

void startAThread2() {  new Thread() {    publicvoid run() {      ...    }  }.start();}
不要直接調用run()方法。總是調用Thread.start()方法,這個方法會建立一條新的線程並使建立的線程調用run()。 參考:java.lang.Thread, java.lang.Runnable。

使用try-finally

I/O流例子:

void writeStuff() throwsIOException {  OutputStream out = newFileOutputStream(...);  try{    out.write(...);  }finally{    out.close();  }}

鎖例子:

void doWithLock(Lock lock) {  lock.acquire();  try{    ...  }finally{    lock.release();  }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.