Java是目前最流行的編程語言之一——它能夠用來編寫Windows程序或者是Web應用,移動應用,網絡程序,消費電子產品,機頂盒設備,它無處不在。 html
有超過30億的設備是運行在Java之上的。根據Oracle的統計數據,光是使用中的Java Card就有有50億。 java
超過900萬程序員選擇使用Java進行開發,它是最受開發人員歡迎的語言,同時也是最流行的開發平臺。 程序員
本文爲那些準Java程序員們準備了一系列廣爲流傳的Java最佳編程實踐: web
若是程序要返回一個不包含任何值的集合,確保返回的是空集合而不是null。這能節省大量的"if else"檢查。 正則表達式
public class getLocationName { return (null==cityName ? "": cityName); }
若是兩個字符串在for循環中使用+操做符進行拼接,那麼每次循環都會產生一個新的字符串對象。這不只浪費內存空間同時還會影響性能。相似的,若是初始化字符串對象,儘可能不要使用構造方法,而應該直接初始化。比方說: shell
//Slower Instantiation String bad = new String("Yet another string object"); //Faster Instantiation String good = "Yet another string object"
建立對象是Java中最昂貴的操做之一。所以最好在有須要的時候再進行對象的建立/初始化。以下: 數據庫
import java.util.ArrayList; import java.util.List; public class Employees { private List Employees; public List getEmployees() { //initialize only when required if(null == Employees) { Employees = new ArrayList(); } return Employees; } }
開發人員常常會發現很難在數組和ArrayList間作選擇。它們兩者互有優劣。如何選擇應該視狀況而定。 編程
import java.util.ArrayList; public class arrayVsArrayList { public static void main(String[] args) { int[] myArray = new int[6]; myArray[7]= 10; // ArraysOutOfBoundException //Declaration of ArrayList. Add and Remove of elements is easy. ArrayList<Integer> myArrayList = new ArrayList<>(); myArrayList.add(1); myArrayList.add(2); myArrayList.add(3); myArrayList.add(4); myArrayList.add(5); myArrayList.remove(0); for(int i = 0; i < myArrayList.size(); i++) { System.out.println("Element: " + myArrayList.get(i)); } //Multi-dimensional Array int[][][] multiArray = new int [3][3][3]; } }
看下下面這段代碼: json
public class shutDownHooksDemo { public static void main(String[] args) { for(int i=0;i<5;i++) { try { if(i==4) { System.out.println("Inside Try Block.Exiting without executing Finally block."); System.exit(0); } } finally { System.out.println("Inside Finally Block."); } } } }
從代碼來看,貌似finally塊中的println語句應該會被執行5次。但當程序運行後,你會發現finally塊只執行了4次。第5次迭代的 時候會觸發exit函數的調用,因而這第5次的finally便永遠也觸發不到了。緣由即是——System.exit會掛起全部線程的執行,包括當前線 程。即使是try語句後的finally塊,只要是執行了exit,便也無力迴天了。 設計模式
在調用System.exit時,JVM會在關閉前執行兩個結束任務:
首先,它會執行完全部經過Runtime.addShutdownHook註冊進來的終止的鉤子程序。這一點很關鍵,由於它會釋放JVM外部的資源。
接下來的即是Finalizer了。多是System.runFinalizersOnExit也多是 Runtime.runFinalizersOnExit。finalizer的使用已經被廢棄有很長一段時間了。finalizer能夠在存活對象上進 行調用,即使是這些對象仍在被其它線程所使用。而這會致使不可預期的結果甚至是死鎖。
public class shutDownHooksDemo { public static void main(String[] args) { for(int i=0;i<5;i++) { final int final_i = i; try { Runtime.getRuntime().addShutdownHook( new Thread() { public void run() { if(final_i==4) { System.out.println("Inside Try Block.Exiting without executing Finally block."); System.exit(0); } } }); } finally { System.out.println("Inside Finally Block."); } } } }
看下這幾行代碼,看看它們是否能用來準確地判斷一個數是奇數?
public boolean oddOrNot(int num) { return num % 2 == 1; }
看似是對的,可是每執行四便會有一個錯誤的結果(用數聽說話)。考慮到負奇數的狀況,它除以2的結果就不會是1。所以,返回值是false,而這樣是不對的。
代碼能夠修改爲這樣:
public boolean oddOrNot(int num) { return (num & 1) != 0; }
這麼寫不光是負奇數的問題解決了,而且仍是通過充分優化過的。由於算術運算和邏輯運行要比乘除運算更高效,計算的結果也會更快。
public class Haha { public static void main(String args[]) { System.out.print("H" + "a"); System.out.print('H' + 'a'); } }
看起來這段代碼會返回"Haha",但實際返回的是Ha169。緣由就是用了雙引號的時候,字符會被看成字符串處理,而若是是單引號的話,字符值會經過一個叫作基礎類型拓寬的操做來轉換成整型值。而後再將值相加獲得169。
內存泄露會致使軟件的性能降級。因爲Java是自動管理內存的,所以開發人員並無太多辦法介入。不過仍是有一些方法可以用來防止內存泄露的。
死鎖出現的緣由有不少。避免死鎖不是一句話就能解決的。一般來講,當某個同步對象在等待另外一個同步對象所擁有的資源上的鎖時,便會產生死鎖。
試着運行下下面的程序。它會告訴你什麼是死鎖。這個死鎖是因爲兩個線程都在等待對方所擁有的資源,所以會產生死鎖。它們會一直等待,沒有誰會先放手。
public class DeadlockDemo { public static Object addLock = new Object(); public static Object subLock = new Object(); public static void main(String args[]) { MyAdditionThread add = new MyAdditionThread(); MySubtractionThread sub = new MySubtractionThread(); add.start(); sub.start(); } private static class MyAdditionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a + b; System.out.println("Addition Thread: " + c); System.out.println("Holding First Lock..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Addition Thread: Waiting for AddLock..."); synchronized (subLock) { System.out.println("Threads: Holding Add and Sub Locks..."); } } } } private static class MySubtractionThread extends Thread { public void run() { synchronized (subLock) { int a = 10, b = 3; int c = a - b; System.out.println("Subtraction Thread: " + c); System.out.println("Holding Second Lock..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Subtraction Thread: Waiting for SubLock..."); synchronized (addLock) { System.out.println("Threads: Holding Add and Sub Locks..."); } } } } }
輸出:
Addition Thread: 13 Subtraction Thread: 7 Holding First Lock... Holding Second Lock... Addition Thread: Waiting for AddLock... Subtraction Thread: Waiting for SubLock...
但若是調用的順序變一下的話,死鎖的問題就解決了。
public class DeadlockSolutionDemo { public static Object addLock = new Object(); public static Object subLock = new Object(); public static void main(String args[]) { MyAdditionThread add = new MyAdditionThread(); MySubtractionThread sub = new MySubtractionThread(); add.start(); sub.start(); } private static class MyAdditionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a + b; System.out.println("Addition Thread: " + c); System.out.println("Holding First Lock..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Addition Thread: Waiting for AddLock..."); synchronized (subLock) { System.out.println("Threads: Holding Add and Sub Locks..."); } } } } private static class MySubtractionThread extends Thread { public void run() { synchronized (addLock) { int a = 10, b = 3; int c = a - b; System.out.println("Subtraction Thread: " + c); System.out.println("Holding Second Lock..."); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("Subtraction Thread: Waiting for SubLock..."); synchronized (subLock) { System.out.println("Threads: Holding Add and Sub Locks..."); } } } } }
輸出:
Addition Thread: 13 Holding First Lock... Addition Thread: Waiting for AddLock... Threads: Holding Add and Sub Locks... Subtraction Thread: 7 Holding Second Lock... Subtraction Thread: Waiting for SubLock... Threads: Holding Add and Sub Locks...
某些Java程序是CPU密集型的,但它們會須要大量的內存。這類程序一般運行得很緩慢,由於它們對內存的需求很大。爲了能提高這類應用的性能,可 得給它們多留點內存。所以,假設咱們有一臺擁有10G內存的Tomcat服務器。在這臺機器上,咱們能夠用以下的這條命令來分配內存:
export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"
在Java中進行操做計時有兩個標準的方法:System.currentTimeMillis()和System.nanoTime()。問題就在於,什麼狀況下該用哪一個。從本質上來說,他們的做用都是同樣的,但有如下幾點不一樣:
System.currentTimeMillis對應的是絕對時間(1970年1 月1日所經歷的毫秒數),而System.nanoTime()則不與任什麼時候間點相關。
Float仍是double
數據類型 | 所用字節 | 有效位數 |
float | 4 | 7 |
double | 8 | 15 |
在對精度要求高的場景下,double類型相對float要更流行一些,理由以下:
大多數處理器在處理float和double上所需的時間都是差很少的。而計算時間同樣的前提下,double類型卻能提供更高的精度。
Java是經過異或操做來進行冪運算的。Java對於冪運算有兩種處理方式:
double square = double a * double a; // Optimized double cube = double a * double a * double a; // Non-optimized double cube = double a * double square; // Optimized double quad = double a * double a * double a * double a; // Non-optimized double quad = double square * double square; // Optimized
double cube = Math.pow(base, exponent);
不到萬不得已不要使用Math.pow。比方說,當指數是小數的時候。由於Math.pow要比乘積慢300-600倍左右。
空指針異常是Java中很常見的異常。當你嘗試調用一個null對象上的方法時便會拋出這個異常。好比:
int noOfStudents = school.listStudents().count;
在上述例子中,school爲空或者listStudents()爲空均可能會拋出了NullPointerException。所以最好檢查下對象是否爲空以免相似狀況。
private int getListOfStudents(File[] files) { if (files == null) throw new NullPointerException("File list cannot be null"); }
JSON是數據存儲及傳輸的一種協議。與XML相比,它更易於使用。因爲它很是輕量級以及自身的一些特性,如今JSON在網絡上已是愈來愈流行 了。常見的數據結構均可以編碼成JSON而後在各個網頁間自由地傳輸。不過在開始編碼前,你得先安裝一個JSON解析器。在下面的例子中,咱們將使用 json.simple庫來完成這項工做 (https://code.google.com/p/json-simple/)。
下面是編碼成JSON串的一個簡單的例子。
import org.json.simple.JSONObject; import org.json.simple.JSONArray; public class JsonEncodeDemo { public static void main(String[] args) { JSONObject obj = new JSONObject(); obj.put("Novel Name", "Godaan"); obj.put("Author", "Munshi Premchand"); JSONArray novelDetails = new JSONArray(); novelDetails.add("Language: Hindi"); novelDetails.add("Year of Publication: 1936"); novelDetails.add("Publisher: Lokmanya Press"); obj.put("Novel Details", novelDetails); System.out.print(obj); } }
輸出:
{"Novel Name":"Godaan","Novel Details":["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}
開發人員要想解析JSON串,首先你得知道它的格式。下面例子有助於你來理解這一點:
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Iterator; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class JsonParseTest { private static final String filePath = "//home//user//Documents//jsonDemoFile.json"; public static void main(String[] args) { try { // read the json file FileReader reader = new FileReader(filePath); JSONParser jsonParser = new JSONParser(); JSONObject jsonObject = (JSONObject)jsonParser.parse(reader); // get a number from the JSON object Long id = (Long) jsonObject.get("id"); System.out.println("The id is: " + id); // get a String from the JSON object String type = (String) jsonObject.get("type"); System.out.println("The type is: " + type); // get a String from the JSON object String name = (String) jsonObject.get("name"); System.out.println("The name is: " + name); // get a number from the JSON object Double ppu = (Double) jsonObject.get("ppu"); System.out.println("The PPU is: " + ppu); // get an array from the JSON object System.out.println("Batters:"); JSONArray batterArray= (JSONArray) jsonObject.get("batters"); Iterator i = batterArray.iterator(); // take each value from the json array separately while (i.hasNext()) { JSONObject innerObj = (JSONObject) i.next(); System.out.println("ID "+ innerObj.get("id") + " type " + innerObj.get("type")); } // get an array from the JSON object System.out.println("Topping:"); JSONArray toppingArray= (JSONArray) jsonObject.get("topping"); Iterator j = toppingArray.iterator(); // take each value from the json array separately while (j.hasNext()) { JSONObject innerObj = (JSONObject) j.next(); System.out.println("ID "+ innerObj.get("id") + " type " + innerObj.get("type")); } } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } catch (ParseException ex) { ex.printStackTrace(); } catch (NullPointerException ex) { ex.printStackTrace(); } } }
jsonDemoFile.json
{ "id": 0001, "type": "donut", "name": "Cake", "ppu": 0.55, "batters": [ { "id": 1001, "type": "Regular" }, { "id": 1002, "type": "Chocolate" }, { "id": 1003, "type": "Blueberry" }, { "id": 1004, "type": "Devil's Food" } ], "topping": [ { "id": 5001, "type": "None" }, { "id": 5002, "type": "Glazed" }, { "id": 5005, "type": "Sugar" }, { "id": 5007, "type": "Powdered Sugar" }, { "id": 5006, "type": "Chocolate with Sprinkles" }, { "id": 5003, "type": "Chocolate" }, { "id": 5004, "type": "Maple" } ] }
The id is: 1 The type is: donut The name is: Cake The PPU is: 0.55 Batters: ID 1001 type Regular ID 1002 type Chocolate ID 1003 type Blueberry ID 1004 type Devil's Food Topping: ID 5001 type None ID 5002 type Glazed ID 5005 type Sugar ID 5007 type Powdered Sugar ID 5006 type Chocolate with Sprinkles ID 5003 type Chocolate ID 5004 type Maple
Java提供了一個庫函數叫作indexOf()。這個方法能夠用在String對象上,它返回的是要查找的字符串所在的位置序號。若是查找不到則會返回-1。
你能夠用下面的代碼來列出目錄下的文件。這個程序會遍歷某個目錄下的全部子目錄及文件,並存儲到一個數組裏,而後經過遍歷數組來列出全部文件。
import java.io.*; public class ListContents { public static void main(String[] args) { File file = new File("//home//user//Documents/"); String[] files = file.list(); System.out.println("Listing contents of " + file.getPath()); for(int i=0 ; i < files.length ; i++) { System.out.println(files[i]); } } }
Java提供了FileInputStream以及FileOutputStream類來進行文件的讀寫操做。FileInputStream的構 造方法會接收輸入文件的路徑做爲入參而後建立出一個文件的輸入流。一樣的,FileOutputStream的構造方法也會接收一個文件路徑做爲入參而後 建立出文件的輸出流。在處理完文件以後,一個很重要的操做就是要記得"close"掉這些流。
import java.io.*; public class myIODemo { public static void main(String args[]) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("//home//user//Documents//InputFile.txt"); out = new FileOutputStream("//home//user//Documents//OutputFile.txt"); int c; while((c = in.read()) != -1) { out.write(c); } } finally { if(in != null) { in.close(); } if(out != null) { out.close(); } } } }
Java提供了Runtime類來執行shell命令。因爲這些是外部的命令,所以異常處理就顯得異常重要。在下面的例子中,咱們將經過一個簡單的例子來演示一下。咱們會在shell命令行中打開一個pdf文件。
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; public class ShellCommandExec { public static void main(String[] args) { String gnomeOpenCommand = "gnome-open //home//user//Documents//MyDoc.pdf"; try { Runtime rt = Runtime.getRuntime(); Process processObj = rt.exec(gnomeOpenCommand); InputStream stdin = processObj.getErrorStream(); InputStreamReader isr = new InputStreamReader(stdin); BufferedReader br = new BufferedReader(isr); String myoutput = ""; while ((myoutput=br.readLine()) != null) { myoutput = myoutput+"\n"; } System.out.println(myoutput); } catch (Exception e) { e.printStackTrace(); } } }
正則表達式的結構摘錄以下(來源: Oracle官網)
字符
x | 字符x |
\ | 反斜槓 |
\0n | 8進制值爲0n的字符(0<=n<=7) |
\0nn | |
\0mnn | 8進制值爲0mnn的字符(0 <= m <= 3, 0<=n<=7) |
\xhh | 16進制值爲0xhh的字符 |
\uhhhh | 16進制值爲0xhhhh的字符 |
\x{h…h} | 16進制值爲0xh…h的字符(Character.MINCODEPOINT <= 0xh…h <= Character.MAXCODEPOINT) |
\t | 製表符(‘\u0009′) |
\n | 換行符(‘\u000A’) |
\r | 回車(‘\u000D’) |
\f | 分頁符(‘\u000C’) |
\a | 警告符(‘\u0007′) |
\e | ESC(‘\u001B’) |
\cx | ctrl+x |
字符分類
[abc] | a, b或c |
[^abc] | abc之外的任意字符 |
[a-zA-Z] | a到z以及A到Z |
[a-d[m-p]] | a到d或者m到p[a-dm-p]則是取並集 |
[a-z&&[def]] | d,e或f(交集) |
[ad-z] | |
[a-z&&[^bc]] | a到z但不包括b和c |
[a-z&&[^m-p]] | a到z但不包括mp:也就是[a-lq-z] |
預約義字符
. | 任意字符,有可能包括換行符 |
\d | 0到9的數字 |
\D | 0到9之外的字符 |
\s | 空格符[ \t\n\x0B\f\r] |
\S | 非空格符[^\s] |
\w | 字母[a-zA-Z_0-9] |
\W | 非字母[^\w] |
邊界匹配
^ | 行首 |
$ | 行末 |
\b | 單詞邊界 |
\A | 輸入的起始位置 |
\G | 前一個匹配的末尾 |
\Z | 輸入的結束位置,僅用於最後的結束符 |
\z | 輸入的結束位置 |
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String pattern = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; private static Pattern mypattern = Pattern.compile(pattern); public static void main( String args[] ){ String valEmail1 = "testemail@domain.com"; String invalEmail1 = "....@domain.com"; String invalEmail2 = ".$$%%@domain.com"; String valEmail2 = "test.email@domain.com"; System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail1)); System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail1)); System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail2)); System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail2)); } public static boolean validateEMailID(String emailID) { Matcher mtch = mypattern.matcher(emailID); if(mtch.matches()){ return true; } return false; } }
有了Java的swing,你即可以編寫GUI應用了。Java所提供的javax包中就包含了swing。使用swing來編寫GUI程序首先需 要繼承下JFrame。而後在裏面添加Box,而後即可以往裏面添加諸如按鈕,多選按鈕,文本框等控件了。這些Box是放在Container的最外層 的。
import java.awt.*; import javax.swing.*; public class SwingsDemo extends JFrame { public SwingsDemo() { String path = "//home//user//Documents//images"; Container contentPane = getContentPane(); contentPane.setLayout(new FlowLayout()); Box myHorizontalBox = Box. createHorizontalBox(); Box myVerticleBox = Box. createVerticalBox(); myHorizontalBox.add(new JButton("My Button 1")); myHorizontalBox.add(new JButton("My Button 2")); myHorizontalBox.add(new JButton("My Button 3")); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image1.jpg"))); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image2.jpg"))); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image3.jpg"))); contentPane.add(myHorizontalBox); contentPane.add(myVerticleBox); pack(); setVisible(true); } public static void main(String args[]) { new SwingsDemo(); } }
在Java中,播放音頻是一個很常見的需求,尤爲是在遊戲開發裏面。
下面這個DEMO演示瞭如何在Java中播放音頻。
import java.io.*; import java.net.URL; import javax.sound.sampled.*; import javax.swing.*; // To play sound using Clip, the process need to be alive. // Hence, we use a Swing application. public class playSoundDemo extends JFrame { // Constructor public playSoundDemo() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("Play Sound Demo"); this.setSize(300, 200); this.setVisible(true); try { URL url = this.getClass().getResource("MyAudio.wav"); AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); Clip clip = AudioSystem.getClip(); clip.open(audioIn); clip.start(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (LineUnavailableException e) { e.printStackTrace(); } } public static void main(String[] args) { new playSoundDemo(); } }
將表格導出成pdf也是一個比較常見的需求。經過itextpdf,導出pdf也不是什麼難事。
import java.io.FileOutputStream; import com.itextpdf.text.Document; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; public class DrawPdf { public static void main(String[] args) throws Exception { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("Employee.pdf")); document.open(); Paragraph para = new Paragraph("Employee Table"); para.setSpacingAfter(20); document.add(para); PdfPTable table = new PdfPTable(3); PdfPCell cell = new PdfPCell(new Paragraph("First Name")); table.addCell(cell); table.addCell("Last Name"); table.addCell("Gender"); table.addCell("Ram"); table.addCell("Kumar"); table.addCell("Male"); table.addCell("Lakshmi"); table.addCell("Devi"); table.addCell("Female"); document.add(table); document.close(); } }
在Java中發送郵件也很簡單。你只需裝一下Java Mail這個jar包,放到你的類路徑裏便可。在下面的代碼中,咱們設置了幾個基礎屬性,而後即可以發送郵件了:
import java.util.*; import javax.mail.*; import javax.mail.internet.*; public class SendEmail { public static void main(String [] args) { String to = "recipient@gmail.com"; String from = "sender@gmail.com"; String host = "localhost"; Properties properties = System.getProperties(); properties.setProperty("mail.smtp.host", host); Session session = Session.getDefaultInstance(properties); try{ MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO,new InternetAddress(to)); message.setSubject("My Email Subject"); message.setText("My Message Body"); Transport.send(message); System.out.println("Sent successfully!"); } catch (MessagingException ex) { ex.printStackTrace(); } } }
許多程序都須要精確的時間計量。Java提供了一個System的靜態方法來支持這一功能:
currentTimeMillis():返回當前時間自新紀元時間以來的毫秒值,long類型。
long startTime = System.currentTimeMillis(); long estimatedTime = System.currentTimeMillis() - startTime;
nanoTime():返回系統計時器當前的精確時間,納秒值,這也是long類型。nanoTime()主要是用於計算相對時間而非絕對時間。
long startTime = System.nanoTime(); long estimatedTime = System.nanoTime() - startTime;
圖片縮放能夠經過AffineTransform來完成。首先要生成一個輸入圖片的圖片緩衝,而後經過它來渲染出縮放後的圖片。
import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class RescaleImage { public static void main(String[] args) throws Exception { BufferedImage imgSource = ImageIO.read(new File("images//Image3.jpg")); BufferedImage imgDestination = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); Graphics2D g = imgDestination.createGraphics(); AffineTransform affinetransformation = AffineTransform.getScaleInstance(2, 2); g.drawRenderedImage(imgSource, affinetransformation); ImageIO.write(imgDestination, "JPG", new File("outImage.jpg")); } }
實現了MouseMotionListner接口後,即可以捕獲鼠標事件了。 當鼠標進入到某個特定區域時便會觸發MouseMoved事件,你便能捕獲到這個移動的動做了。經過一個例子來看下:
import java.awt.event.*; import javax.swing.*; public class MouseCaptureDemo extends JFrame implements MouseMotionListener { public JLabel mouseHoverStatus; public static void main(String args[]) { new MouseCaptureDemo(); } MouseCaptureDemo() { setSize(500, 500); setTitle("Frame displaying Coordinates of Mouse Motion"); mouseHoverStatus = new JLabel("No Mouse Hover Detected.", JLabel.CENTER); add(mouseHoverStatus); addMouseMotionListener(this); setVisible(true); } public void mouseMoved(MouseEvent e) { mouseHoverStatus.setText("Mouse Cursor Coordinates => X:"+e.getX()+" | Y:"+e.getY()); } public void mouseDragged(MouseEvent e) {} }
在Java中有兩種寫文件的方式:FileOutputStream與FileWriter。開發人員常常會在它們之間猶豫不決。下面這個例子能幫忙你更好地理解在不一樣的場景下應該選擇何種方案。首先咱們來看一下實現:
使用FileOutputStream:
File foutput = new File(file_location_string); FileOutputStream fos = new FileOutputStream(foutput); BufferedWriter output = new BufferedWriter(new OutputStreamWriter(fos)); output.write("Buffered Content");
使用FileWriter:
FileWriter fstream = new FileWriter(file_location_string); BufferedWriter output = new BufferedWriter(fstream); output.write("Buffered Content");
根據Java的接口規範:
FileOutputStream是用於寫入原始字節流好比圖片流數據。若是是要寫入字符流,則應該考慮使用FileWriter。
這樣就很清楚了,寫圖片應該使用FileOutputStream而寫文本則應該選擇FileWriter。
Java提供了許多集合類——好比,Vector,Stack,Hashtable等。因此鼓勵開發人員儘量地使用這些集合類有以下緣由:
在大型軟件系統中,代碼的可維護性是件頗有挑戰的工做。新加入的開發人員常常會抱怨這些狀況:單片代碼(Monolithic Code),意大利麪式代碼(spaghetti code, 經常使用於描述捆綁在一塊兒而且低內聚的類和方法)。保持代碼的整潔與可維護有一條很簡單的規則:
單一職責原則 | |
開閉原則 | 開發人員應當優先考慮擴展示有的軟件功能,而不是是修改它。 |
里氏替換原則 | 子類必須可以替換掉他們的父類型 |
接口隔離原則 | 和單一職責原則相似,但它特指的是接口層。每一個接口都應當只負責一項任務。 |
依賴反轉原則 | 依賴抽象而不是具體實現。也就是說每一個模塊都應當經過一個抽象層與其它模塊進行解耦。 |
設計模式能幫助開發人員更好地在軟件中應用軟件的設計準則。它還爲開發人員提供了跨語言的通用平臺。設計模式中的標準術語能讓開發人員更容易進行溝通。
不要上來就開始寫代碼。制定計劃,準備,編寫文檔,檢查而後再去實現。首先,先把需求記下來。而後去準備設計文檔。合理地去假設舉證。互相review方案而後進行確認。
==是用來比較對象引用的,它會檢查兩個操做數指向的是否是同一個對象(不是相同的對象,而是同一個對象)。而"equals"則比較的是兩個字符串是否是相同(假設是字符串對象)。
只有當確實有必要的時候才使用浮點數。比方說,使用浮點數來表示盧比或者派薩就很容易產生問題——這種狀況應當使用BigDecimal。而浮點數更多地是用於測量。
最後我想給你們推薦一下學習Java的一些相關資料。
原創文章轉載請註明出處:Java新手問題集錦