Java筆記:實用工具
一、解析字符串
StringTokenizer將字符串分隔為一系列獨立部分,通常稱為字符分析器或掃描器。使用StringTokenizer,需要指定一個輸入字符串和一個包含定界符的字符串。默認的定界符由包括空格、制表符、換頁符、換行符以及回車符在內的空白字符構成。
import java.util.StringTokenizer; class Solution { public static void main(String[] args) { String del = "+-*/()="; String str = "(1+2)/(3+4)*(5-6)"; StringTokenizer tokenAView Code= new StringTokenizer(str, del);//不返回分隔符 while (tokenA.hasMoreTokens()) System.out.println(tokenA.nextToken());//1 2 3 4 5 6 StringTokenizer tokenB = new StringTokenizer(str, del, true);//返回分隔符 while (tokenB.hasMoreTokens()) System.out.println(tokenB.nextToken());//( 1 + 2 ) / ( 3 + 4 ) * ( 5 - 6 ) } }
二、特殊類型數組
BitSet類創建特殊類型的數組,這類數組的元素是布爾值形式的位值。數組可以根據需要增加大小,與位向量類相似。
import java.util.BitSet; class Solution { public static void main(String[] args) { BitSet bitsA = new BitSet(16);//初始大小100 所有位默認為false BitSet bitsB = new BitSet(16);View Codefor (int i = 0; i < 16; i++) { if (i % 2 == 0) bitsA.set(i); if (i % 5 == 0) bitsB.set(i); } System.out.println(bitsA); System.out.println(bitsB); bitsB.or(bitsA);//或運算 System.out.println(bitsB); bitsA.and(bitsB);//與運算 System.out.println(bitsA); bitsB.xor(bitsA);//異或運算 System.out.println(bitsB); } }
三、空值處理
處理值可能存在,也可能不存在的情況,如果引用null值會引發空指針異常,需要頻繁地檢查。這種情況可以使用Optional、OptionalDouble、OptionalInt和OptionalLong,可調用Optional的isPresent方法判斷值是否存在,調用get方法獲取值。為了減少訪問的開銷,Optional提供了orElse方法,若對象包含值則返回,否則返回默認值。Optional沒有構造函數,需要調用靜態方法進行實例化。
import java.util.Optional; class Solution { public static void main(String[] args) { Optional<String> noValue = Optional.empty();//空對象 Optional<String> hasValue = Optional.of("ABCDE");//非空對象 if (noValue.isPresent()) System.out.println(noValue.get()); if (hasValue.isPresent()) System.out.println(hasValue.get()); String def = noValue.orElse("Default");//指定默認值 System.out.println(def);//Default } }View Code
四、日期時間
Date封裝了當前日期和時間,使用Date的特性不允許獲取日期或時間的單個組成部分,只能以毫秒為單位獲取日期和時間,或者通過toString獲取時間的默認字符串表現形式。
import java.util.Date; class Solution { public static void main(String[] args) { Date date = new Date(); System.out.println(date);//Sun Feb 25 16:04:28 CST 2018 long ms = date.getTime(); System.out.println(ms);//距1970/1/1 00:00 1519545868925ms } }View Code
Calendar抽象類提供了一套將毫秒數形式的時間轉換成時間組成部分的方法。
import java.util.Calendar; class Solution { public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH)); System.out.println(calendar.get(Calendar.DATE)); calendar.set(Calendar.HOUR, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); System.out.println(calendar.getTime()); } }View Code
GregorianCalendar類是Calendar抽象類的具體實現。Calendar的getInstance方法通常會返回一個GregorianCalendar對象,該對象使用默認地區和時區下的當前日期和時間進行初始化。
import java.util.Calendar; import java.util.GregorianCalendar; class Solution { public static void main(String[] args) { GregorianCalendar calendar = new GregorianCalendar(1998,3,21); System.out.println(calendar.isLeapYear(calendar.get(Calendar.YEAR)));//判斷閏年 } }View Code
五、隨機數
Random類是偽隨機數生成器,之所以稱為偽隨機數,是因為它們只是簡單的均勻部分分布序列。如果指定隨機種子,就為隨機序列定義了起始點。使用相同的種子會得到相同的隨機序列,隨機種子通常選擇當前時間,這種方式減少了得到重復序列的可能。
import java.util.Random; class Solution { public static void main(String[] args) { Random random = new Random(); random.setSeed(System.currentTimeMillis());//設置種子 System.out.println(random.nextBoolean());//隨機布爾值 byte[] bytes = new byte[100]; random.nextBytes(bytes);//隨機值填充數組 System.out.println(random.nextInt(100));//0-100間的隨機數 System.out.println(random.nextGaussian());//高斯分布隨機數(即正態分布) } }View Code
六、觀察對象
Observable用於創建可以被程序其他部分觀察的子類,當這種子類發生變化時,觀察類就會註意到。觀察類必須實現Observer接口,該接口定義了update方法。當觀察者註意到被觀察者的變化時,會調用update方法。
被觀察對象必須滿足兩個簡單規則:被觀察對象發生變化必須調用setChanged方法,通知觀察者發生變化時必須調用notifyObservers方法才會使觀察者調用update方法。
import java.util.Observable; import java.util.Observer; class WatcherA implements Observer { @Override public void update(Observable obj, Object arg) { System.out.println(arg); } } class WatcherB implements Observer { @Override public void update(Observable o, Object arg) { if ((Integer) arg == 0) System.out.println("Over"); } } class Watched extends Observable { void change() { for (int i = 10; i >= 0; i--) { setChanged(); notifyObservers(i); try { Thread.sleep(1000); } catch (InterruptedException exc) { System.out.println("Thread interrupted"); } } } } class Solution { public static void main(String[] args) { Watched watched = new Watched(); WatcherA watcherA = new WatcherA(); WatcherB watcherB = new WatcherB(); watched.addObserver(watcherA); watched.addObserver(watcherB); watched.change(); } }View Code
七、定時任務
Timer和TimerTask可以創建在後臺允許、等待特定時刻的線程。當時間達到時執行鏈接到線程的任務。雖然使用Thread同樣可以實現,但是Timer和TimerTask簡化了過程。Timer用於安排任務,被安排的任務必須是TimerTask實例。
import java.util.Timer; import java.util.TimerTask; class MyTimerTask extends TimerTask { @Override public void run() { System.out.println("MyTimerTask.run called"); } } class Solution { public static void main(String[] args) { Timer timer = new Timer(); MyTimerTask timerTask = new MyTimerTask(); timer.schedule(timerTask, 1000, 500);//1s後執行,之後0.5s重復一次 try { Thread.sleep(5000); } catch (InterruptedException exc) { System.out.println("Thread interrupted"); } timer.cancel();//結束任務 } }View Code
八、格式化輸出
Formatter提供了格式轉換功能,從而可以采用各種方式顯示數字、字符串以及日期時間。操作方式類似於C語言的printf函數。
import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("Hello%c%s", ‘.‘, "World"); System.out.println(formatter);//Hello.World formatter.close(); } }View Code
格式化日期時間。
import java.util.Calendar; import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); Calendar calendar = Calendar.getInstance(); formatter.format("%tc\n", calendar);//標準日期時間 formatter.format("%tC\n", calendar);//年份前兩位數字 formatter.format("%ty\n", calendar);//年份後兩位數字 formatter.format("%tY\n", calendar);//年份 formatter.format("%tb\n", calendar);//月份簡稱 formatter.format("%tB\n", calendar);//月份全稱 formatter.format("%tm\n", calendar);//月(01-13) formatter.format("%ta\n", calendar);//星期簡稱 formatter.format("%tA\n", calendar);//星期全稱 formatter.format("%te\n", calendar);//日(1-31) formatter.format("%td\n", calendar);//日(01-31) formatter.format("%tj\n", calendar);//日(001-366) formatter.format("%tD\n", calendar);//月/日/年 formatter.format("%tF\n", calendar);//年-月-日 formatter.format("%tH\n", calendar);//小時(00-23) formatter.format("%tI\n", calendar);//小時(01-12) formatter.format("%tp\n", calendar);//AM/PM formatter.format("%tM\n", calendar);//分(00-59) formatter.format("%tS\n", calendar);//秒(00-60) formatter.format("%tL\n", calendar);//毫秒(000-999) formatter.format("%tN\n", calendar);//納秒(000000000-999999999) formatter.format("%tr\n", calendar);//小時:分鐘:秒鐘(12小時格式) formatter.format("%tR\n", calendar);//小時:分鐘:秒鐘(24小時格式) formatter.format("%tZ\n", calendar);//時區名 System.out.println(formatter); formatter.close(); } }View Code
指定字段寬度。
import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("(%5d)\n", 0);//寬度為5 默認使用空格填充 formatter.format("(%05d)\n", 0);//寬度為5 使用0填充 System.out.println(formatter); formatter.close(); } }View Code
指定精度。
import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("%.2f\n", 0.123456);//保留兩位小數 formatter.format("%10.2f\n", 0.123456);//保留兩位小數並指定寬度為10 formatter.format("%5.10s\n", "Hello World");//字符串長度位於[5, 10]內 System.out.println(formatter); formatter.close(); } }View Code
對齊輸出。
import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("%-5.10s\n", "ABC");//左對齊 System.out.println(formatter); formatter.close(); } }View Code
逗號分隔符。
import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("%,d", 1000000000);//1,000,000,000 System.out.println(formatter); formatter.close(); } }View Code
參數引索。
import java.util.Calendar; import java.util.Formatter; class Solution { public static void main(String[] args) { Formatter formatter = new Formatter(); formatter.format("%2$d %1$d %3$d\n", 30, 20, 10);//20 30 10 指定參數引索 formatter.format("%te %<tB %<tY\n", Calendar.getInstance());//重復使用參數 System.out.println(formatter); formatter.close(); } }View Code
自動釋放資源。
import java.util.Calendar; import java.util.Formatter; class Solution { public static void main(String[] args) { try (Formatter formatter = new Formatter()) { formatter.format("%tc", Calendar.getInstance()); System.out.println(formatter); } } }View Code
九、格式化輸入
Scanner讀取格式化輸入,並將輸入轉換成相應的二進制形式。
讀取並輸出文件。
import java.io.FileReader; import java.io.IOException; import java.util.Scanner; class Solution { public static void main(String[] args) { try { FileReader reader = new FileReader("file.txt"); Scanner scanner = new Scanner(reader); while (scanner.hasNextLine()) System.out.println(scanner.nextLine()); scanner.close(); } catch (IOException exc) { System.out.println("IO exception caught"); } } }View Code
設置定界符。
import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; class Solution { public static void main(String[] args) { try (FileWriter writer = new FileWriter("file.txt")) { writer.write("1,2,3,4,5"); } catch (IOException exc) { System.out.println("IO exception caught"); } try (Scanner scanner = new Scanner(new FileReader("file.txt"))) { scanner.useDelimiter(","); while (scanner.hasNextInt()) System.out.println(scanner.nextInt()); } catch (IOException exc) { System.out.println("IO exception caught"); } } }View Code
Java筆記:實用工具