Java 8 (2014/03 釋出) 是 Java 歷史上**變革最大**的版本,引入函數式程式設計、Stream 流式處理、新日期時間 API、預設方法等,徹底改變了 Java 程式碼風格與開發效率。本文系統梳理十大核心特性,附完整可執行範例。
介面可擁有實作,不破壞現有實作類,實現「介面演進」。
interface Formula {
double calculate(int a);
default double sqrt(int a) { return Math.sqrt(a); } // 預設方法
static double pi() { return Math.PI; } // 靜態方法
}
Formula f = new Formula() {
public double calculate(int a) { return sqrt(a * 100); }
};
System.out.println(f.calculate(100)); // 100.0
System.out.println(f.sqrt(16)); // 4.0
System.out.println(Formula.pi()); // 3.14159...
將程式碼當作資料傳遞,替代匿名內部類。
List names = Arrays.asList("peter", "anna", "mike", "xenia");
// 舊寫法
Collections.sort(names, new Comparator() {
public int compare(String a, String b) { return b.compareTo(a); }
});
// Lambda
Collections.sort(names, (a, b) -> b.compareTo(a));
// 更簡短 (型別推導)
names.sort((a, b) -> b.compareTo(a));
僅含**一個抽象方法**的介面,可隱式轉換為 Lambda。
@FunctionalInterface
interface Converter { T convert(F from); }
Converter c = Integer::valueOf; // 方法引用
Integer result = c.convert("123"); // 123
// 靜態方法引用
Converter c1 = Integer::valueOf;
// 實例方法引用
String str = "Java";
Converter c2 = str::startsWith;
// 建構子引用
interface PersonFactory { Person create(String first, String last); }
PersonFactory factory = Person::new;
Person p = factory.create("Peter", "Parker");
final (不可變更),int n=1; c = x -> x+n; 合法;n=2; 編譯錯誤。| 介面 | 參數 | 回傳 | 用途 |
|---|---|---|---|
| Predicate | T | boolean | 條件判斷 |
| Function | T | R | 轉換 |
| Supplier | 無 | T | 供給 |
| Consumer | T | void | 消費 |
| Comparator | T,T | int | 比較 |
Predicate nonEmpty = s -> !s.isEmpty();
Function toInt = Integer::valueOf;
Supplier personSupplier = Person::new;
Consumer printer = System.out::println;
Comparator byName = (p1,p2) -> p1.getName().compareTo(p2.getName());
Optional opt = Optional.of("bam");
opt.isPresent(); // true
opt.get(); // "bam"
opt.orElse("fallback"); // "bam"
opt.ifPresent(s -> System.out.println(s.charAt(0))); // 'b'
// 實戰:避免巢狀 if
public String getCity(User user) {
return Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("Unknown");
}
集合操作聲明式、可並行、管道化。
List list = Arrays.asList("ddd2","aaa2","bbb1","aaa1","bbb3","ccc","bbb2","ddd1");
// Filter + Sort + Map + Collect
List result = list.stream()
.filter(s -> s.startsWith("a"))
.sorted()
.map(String::toUpperCase)
.collect(Collectors.toList()); // [AAA1, AAA2]
// Match
boolean anyA = list.stream().anyMatch(s -> s.startsWith("a")); // true
long countB = list.stream().filter(s -> s.startsWith("b")).count(); // 3
// Reduce
Optional reduced = list.stream()
.sorted()
.reduce((s1,s2) -> s1 + "#" + s2); // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"
// 並行流:僅將 .stream() 改為 .parallelStream()
long t0 = System.nanoTime();
list.parallelStream().sorted().count();
System.out.println("並行耗時: " + (System.nanoTime()-t0)/1e6 + " ms");
不可變、執行緒安全、領域驅動設計。
// 核心類別
LocalDate date = LocalDate.now(); // 2024-05-20
LocalTime time = LocalTime.now(); // 14:30:00
LocalDateTime dt = LocalDateTime.now(); // 2024-05-20T14:30:00
ZonedDateTime zdt = ZonedDateTime.now(); // 2024-05-20T14:30:00+08:00[Asia/Taipei]
Instant now = Instant.now(); // 時間戳 (UTC)
// 運算
LocalDate tomorrow = date.plusDays(1);
LocalDate nextMonth = date.plus(1, ChronoUnit.MONTHS);
Period period = Period.between(date, LocalDate.of(2025,1,1));
// 格式化 (執行緒安全)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String formatted = dt.format(fmt);
LocalDateTime parsed = LocalDateTime.parse("2024-12-31 23:59", fmt);
@Repeatable(Schedules.class)
@interface Schedule { String value(); }
@interface Schedules { Schedule[] value(); }
// Java 8 可直接重複使用
@Schedule("day")
@Schedule("night")
class MyTask {}
// 反射獲取
Schedule[] schedules = MyTask.class.getAnnotationsByType(Schedule.class);
// 類型註解 (JSR 308)
@NonNull String str = (@NonNull String) obj; // 強制轉型處標註
Arrays.parallelSort — 並行排序大陣列StampedLock — 樂觀讀鎖,高併發讀多寫少場景優於 ReentrantReadWriteLockCompletableFuture — 非阻塞非同步程式設計,支援組合、異常處理、回調StringJoiner / String.join — 簡化字串拼接Base64 編解碼終於進標準庫Java 8 以 Lambda + Stream + Optional 為核心,推動 Java 邁向函數式、聲明式、並行友善的新時代。掌握這十大特性,即可寫出更簡潔、安全、高效的現代 Java 程式碼。