一、解析字符串
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 tokenA = 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); for (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 } }
四、日期时间
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 } }
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()); } }
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)));//判断闰年 } }
五、随机数
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());//高斯分布随机数(即正态分布) } }
六、观察对象
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(); } }
七、定时任务
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();//结束任务 } }
八、格式化输出
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(); } }
格式化日期时间。
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(); } }
指定字段宽度。
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(); } }
指定精度。
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(); } }
对齐输出。
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(); } }
逗号分隔符。
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(); } }
参数引索。
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(); } }
自动释放资源。
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); } } }
九、格式化输入
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"); } } }
设置定界符。
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"); } } }