Java习惯用法总结
在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的。在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法。(Joshua Bloch的《Effective Java》对这个话题给出了更详尽的论述,可以从这本书里学习更多的用法。)
我把本文的所有代码都放在公共场所里。你可以根据自己的喜好去复制和修改任意的代码片段,不需要任何的凭证。 目录
实现equals()class Person { String name; int birthYear; byte[] raw; public boolean equals(Object obj) { if (!obj instanceof Person) return false; Person other = (Person)obj; return name.equals(other.name) && birthYear == other.birthYear && Arrays.equals(raw,other.raw); } public int hashCode() { ... } }
实现hashCode()class Person { String a; Object b; byte c; int[] d; public int hashCode() { return a.hashCode() + b.hashCode() + c + Arrays.hashCode(d); } public boolean equals(Object o) { ... } }
实现compareTo()class Person implements Comparable<Person> { String firstName; String lastName; int birthdate; // Compare by firstName,break ties by lastName,finally break ties by birthdate public int compareTo(Person other) { if (firstName.compareTo(other.firstName) != 0) return firstName.compareTo(other.firstName); else if (lastName.compareTo(other.lastName) != 0) return lastName.compareTo(other.lastName); else if (birthdate < other.birthdate) return -1; else if (birthdate > other.birthdate) return 1; else return 0; } }
实现clone()class Values implements Cloneable { String abc; double foo; int[] bars; Date hired; public Values clone() { try { Values result = (Values)super.clone(); result.bars = result.bars.clone(); result.hired = result.hired.clone(); return result; } catch (CloneNotSupportedException e) { // Impossible throw new AssertionError(e); } } }
使用StringBuilder或StringBuffer// join(["a","b","c"]) -> "a and b and c" String join(List<String> strs) { StringBuilder sb = new StringBuilder(); boolean first = true; for (String s : strs) { if (first) first = false; else sb.append(" and "); sb.append(s); } return sb.toString(); }
生成一个范围内的随机整数Random rand = new Random(); // Between 1 and 6,inclusive int diceRoll() { return rand.nextInt(6) + 1; }
使用Iterator.remove()void filter(List<String> list) { for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) { String item = iter.next(); if (...) iter.remove(); } }
返转字符串String reverse(String s) { return new StringBuilder(s).reverse().toString(); }
启动一条线程下面的三个例子使用了不同的方式完成了同样的事情。 实现Runnnable的方式: void startAThread0() { new Thread(new MyRunnable()).start(); } class MyRunnable implements Runnable { public void run() { ... } } 继承Thread的方式: void startAThread1() { new MyThread().start(); } class MyThread extends Thread { public void run() { ... } } 匿名继承Thread的方式: void startAThread2() { new Thread() { public void run() { ... } }.start(); }
使用try-finallyI/O流例子: void writeStuff() throws IOException { OutputStream out = new FileOutputStream(...); try { out.write(...); } finally { out.close(); } } 锁例子: void doWithLock(Lock lock) { lock.acquire(); try { ... } finally { lock.release(); } }
从输入流里读取字节数据InputStream in = (...); try { while (true) { int b = in.read(); if (b == -1) break; (... process b ...) } } finally { in.close(); }
从输入流里读取块数据InputStream in = (...); try { byte[] buf = new byte[100]; while (true) { int n = in.read(buf); if (n == -1) break; (... process buf with offset=0 and length=n ...) } } finally { in.close(); }
从文件里读取文本BufferedReader in = new BufferedReader( new InputStreamReader(new FileInputStream(...),"UTF-8")); try { while (true) { String line = in.readLine(); if (line == null) break; (... process line ...) } } finally { in.close(); }
向文件里写文本PrintWriter out = new PrintWriter( new OutputStreamWriter(new FileOutputStream(...),"UTF-8")); try { out.print("Hello "); out.print(42); out.println(" world!"); } finally { out.close(); }
预防性检测(Defensive checking)数值int factorial(int n) { if (n < 0) throw new IllegalArgumentException("Undefined"); else if (n >= 13) throw new ArithmeticException("Result overflow"); else if (n == 0) return 1; else return n * factorial(n - 1); }
预防性检测对象int findIndex(List<String> list,String target) { if (list == null || target == null) throw new NullPointerException(); ... }
预防性检测数组索引void frob(byte[] b,int index) { if (b == null) throw new NullPointerException(); if (index < 0 || index >= b.length) throw new IndexOutOfBoundsException(); ... }
预防性检测数组区间void frob(byte[] b,int off,int len) { if (b == null) throw new NullPointerException(); if (off < 0 || off > b.length || len < 0 || b.length - off < len) throw new IndexOutOfBoundsException(); ... }
填充数组元素使用循环: // Fill each element of array 'a' with 123 byte[] a = (...); for (int i = 0; i < a.length; i++) a[i] = 123; (优先)使用标准库的方法: Arrays.fill(a,(byte)123);
复制一个范围内的数组元素使用循环: // Copy 8 elements from array 'a' starting at offset 3 // to array 'b' starting at offset 6,// assuming 'a' and 'b' are distinct arrays byte[] a = (...); byte[] b = (...); for (int i = 0; i < 8; i++) b[6 + i] = a[3 + i]; (优先)使用标准库的方法: System.arraycopy(a,3,b,6,8);
调整数组大小使用循环(扩大规模): // Make array 'a' larger to newLen byte[] a = (...); byte[] b = new byte[newLen]; for (int i = 0; i < a.length; i++) // Goes up to length of A b[i] = a[i]; a = b; 使用循环(减小规模): // Make array 'a' smaller to newLen byte[] a = (...); byte[] b = new byte[newLen]; for (int i = 0; i < b.length; i++) // Goes up to length of B b[i] = a[i]; a = b; (优先)使用标准库的方法: a = Arrays.copyOf(a,newLen);
把4个字节包装(packing)成一个intint packBigEndian(byte[] b) { return (b[0] & 0xFF) << 24 | (b[1] & 0xFF) << 16 | (b[2] & 0xFF) << 8 | (b[3] & 0xFF) << 0; } int packLittleEndian(byte[] b) { return (b[0] & 0xFF) << 0 | (b[1] & 0xFF) << 8 | (b[2] & 0xFF) << 16 | (b[3] & 0xFF) << 24; }
把int分解(Unpacking)成4个字节byte[] unpackBigEndian(int x) { return new byte[] { (byte)(x >>> 24),(byte)(x >>> 16),(byte)(x >>> 8),(byte)(x >>> 0) }; } byte[] unpackLittleEndian(int x) { return new byte[] { (byte)(x >>> 0),(byte)(x >>> 24) }; }
原文链接: nayuki 翻译:importnew (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |