1. 集合工厂方法:一行代码创建不可变集合

// JDK9方式
List<String> list = List.of("Java", "Kotlin", "Scala");
Set<String> set = Set.of("Java", "Kotlin", "Scala");
Map<String, Integer> map = Map.of( "Java", 1995, "Kotlin", 2011, "Scala", 2004 );

2. InputStream.transferTo():流复制不再繁琐

// JDK9方式 - 简洁明了 
try (
    InputStream is = new FileInputStream("source.txt"); 
    OutputStream os = new FileOutputStream("target.txt")
) { 
    is.transferTo(os); // 一行代码搞定
}

3. 局部变量类型推断(var):告别冗长的变量声明

// JDK10方式 - 简洁明了 
var customersByCity = new HashMap<String, List<Customer>>(); 
var reader = new BufferedReader(new FileReader("data.txt"));
var connection = new URL("https://example.com").openConnection(); 
// 在for循环中特别有用 
for (var entry : customersByCity.entrySet()) { 
    var city = entry.getKey(); 
    var customers = entry.getValue(); 
    // ...
}
//注:
// 1.var只能用于局部变量,不能用于字段、方法参数或返回类型
// 2.声明时必须初始化变量
// 3.不要过度使用,当类型不明显时应该明确声明类型

4. 不可修改集合的复制方法:集合转换更安全(JDK10)

// 原始集合
List<String> original = new ArrayList<>(List.of("Java", "Kotlin", "Scala"));
Set<Integer> originalSet = new HashSet<>(Set.of(1, 2, 3));
Map<String, Integer> originalMap = new HashMap<>(Map.of("one", 1, "two", 2));

// 创建不可修改的副本
List<String> copy = List.copyOf(original);
Set<Integer> copiedSet = Set.copyOf(originalSet);
Map<String, Integer> copiedMap = Map.copyOf(originalMap);

// 修改原集合不影响副本
original.add("Groovy");
System.out.println(original); // [Java, Kotlin, Scala, Groovy]
System.out.println(copy);     // [Java, Kotlin, Scala]

// 尝试修改副本会抛出异常
try {
    copy.add("Clojure"); // 抛出 UnsupportedOperationException
} catch (UnsupportedOperationException e) {
    System.out.println("Cannot modify immutable copy");
}

5. String新方法:文本处理得心应手(JDK11)

// 1. lines() - 按行分割字符串
String multiline = "JavanKotlinnScala";
multiline.lines()
    .map(String::toUpperCase)
    .forEach(System.out::println);

// 2. strip(), stripLeading(), stripTrailing() - 去除空白字符
String text = "  Hello World  ";
System.out.println(">" + text.strip() + "<");          // >Hello World<
System.out.println(">" + text.stripLeading() + "<");   // >Hello World  <
System.out.println(">" + text.stripTrailing() + "<");  // >  Hello World<

// strip()与trim()的区别: strip()识别更多的Unicode空白字符
String unicodeWhitespace = "u2005Hellou2005";
System.out.println(">" + unicodeWhitespace.trim() + "<");   // >⠀Hello⠀<
System.out.println(">" + unicodeWhitespace.strip() + "<");  // >Hello<

// 3. isBlank() - 检查字符串是否为空白
System.out.println("  ".isBlank());     // true
System.out.println("".isBlank());       // true
System.out.println(" a ".isBlank());    // false

// 4. repeat() - 重复字符串
String star = "*";
System.out.println(star.repeat(10));    // **********
System.out.println("=".repeat(20));     // ====================

6. Files新方法:文件读写一步到位(JDK11)

// 读取文件为String
String content = Files.readString(Path.of("config.json"));

// 写入String到文件
Files.writeString(Path.of("output.txt"), "Hello Java 11!");

// 使用指定编码
String content = Files.readString(Path.of("data.txt"), StandardCharsets.UTF_8);
Files.writeString(Path.of("log.txt"), "Logged at: " + LocalDateTime.now(), 
                 StandardCharsets.UTF_8);

// 写入字符串集合
List<String> lines = List.of("Line 1", "Line 2", "Line 3");
Files.write(Path.of("lines.txt"), lines);

7. Compact Number Formatting:数字的可读性表示(JDK12)

// 创建简短格式的格式化器
NumberFormat shortFormatter = NumberFormat.getCompactNumberInstance(
    Locale.US, NumberFormat.Style.SHORT);

// 格式化数字
System.out.println(shortFormatter.format(1000));       // 1K
System.out.println(shortFormatter.format(1500));       // 2K (四舍五入)
System.out.println(shortFormatter.format(1000000));    // 1M
System.out.println(shortFormatter.format(1000000000)); // 1B

// 长格式
NumberFormat longFormatter = NumberFormat.getCompactNumberInstance(
    Locale.US, NumberFormat.Style.LONG);
System.out.println(longFormatter.format(1000));        // 1 thousand
System.out.println(longFormatter.format(1000000));     // 1 million

// 其他语言的格式化
NumberFormat germanFormatter = NumberFormat.getCompactNumberInstance(
    Locale.GERMANY, NumberFormat.Style.SHORT);
System.out.println(germanFormatter.format(1000));      // 1.000

NumberFormat chineseFormatter = NumberFormat.getCompactNumberInstance(
    Locale.CHINA, NumberFormat.Style.SHORT);
System.out.println(chineseFormatter.format(1000));     // 1千
System.out.println(chineseFormatter.format(1000000));  // 100万

// 自定义精度
shortFormatter.setMaximumFractionDigits(1);
System.out.println(shortFormatter.format(1234));       // 1.2K
System.out.println(shortFormatter.format(1500));       // 1.5K

8. Switch表达式:更简洁的分支处理(JDK14)

// 传统switch语句
String result;
DayOfWeek day = LocalDate.now().getDayOfWeek();

switch (day) {
    case MONDAY:
    case TUESDAY:
    case WEDNESDAY:
    case THURSDAY:
    case FRIDAY:
        result = "Weekday";
        break;
    case SATURDAY:
    case SUNDAY:
        result = "Weekend";
        break;
    default:
        result = "Invalid day";
        break;
}

// 新的switch表达式
String result = switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Weekday";
    case SATURDAY, SUNDAY -> "Weekend";
    default -> "Invalid day";
};

// 复杂表达式,带代码块
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> {
        System.out.println("Six letters day");
        yield 6;
    }
    case TUESDAY -> {
        System.out.println("Seven letters day");
        yield 7;
    }
    case THURSDAY, SATURDAY -> {
        System.out.println("Eight letters day");
        yield 8;
    }
    case WEDNESDAY -> {
        System.out.println("Nine letters day");
        yield 9;
    }
    default -> {
        throw new IllegalStateException("Invalid day: " + day);
    }
};

9. 文本块:多行字符串不再痛苦(JDK15)

// 传统多行字符串
String json = "{n" +
              "  "name": "John Doe",n" +
              "  "age": 30,n" +
              "  "address": {n" +
              "    "street": "123 Main St",n" +
              "    "city": "Anytown"n" +
              "  }n" +
              "}";

// 使用文本块
String json = """
              {
                "name": "John Doe",
                "age": 30,
                "address": {
                  "street": "123 Main St",
                  "city": "Anytown"
                }
              }
              """;

// HTML示例
String html = """
              <html>
                <body>
                  <h1>Hello, World!</h1>
                </body>
              </html>
              """;

// SQL查询
String query = """
               SELECT id, first_name, last_name
               FROM employees
               WHERE department_id = ?
               ORDER BY last_name, first_name
               """;

10. instanceof模式匹配:类型检查与转换合二为一(JDK16)

// 传统方式
if (obj instanceof String) {
    String s = (String) obj;
    if (s.length() > 5) {
        System.out.println(s.toUpperCase());
    }
}

// 使用模式匹配
if (obj instanceof String s && s.length() > 5) {
    System.out.println(s.toUpperCase());
}

// 在复杂条件中使用
if (obj instanceof String s && s.length() > 10 
    || obj instanceof List<?> list && list.size() > 5) {
    // 使用s或list
}

// 与switch配合使用(JDK17预览特性)
Object value = getValue();
switch (value) {
    case String s when s.length() > 5 -> System.out.println("Long string: " + s);
    case String s -> System.out.println("Short string: " + s);
    case List<?> l -> System.out.println("List with " + l.size() + " elements");
    default -> System.out.println("Unknown type");
}

11. 增强的伪随机数生成器:更灵活、可预测的随机数(JDK17)

// 获取默认的随机数生成器
RandomGenerator random = RandomGenerator.getDefault();
System.out.println(random.nextInt(100)); // 0-99之间的随机数

// 使用特定算法的生成器
RandomGenerator xoroshiro = RandomGenerator.of("Xoroshiro128PlusPlus");
System.out.println(xoroshiro.nextLong());

// 使用L32X64MixRandom - 平衡了速度和质量的算法
RandomGenerator fastRandom = RandomGenerator.of("L32X64MixRandom");
for (int i = 0; i < 5; i++) {
    System.out.println(fastRandom.nextInt(1000));
}

// 创建可复现的随机数序列 (使用相同的种子)
RandomGenerator seeded = RandomGenerator.of("Xoshiro256PlusPlus");
((SplittableRandomGenerator) seeded).setSeed(42);
for (int i = 0; i < 5; i++) {
    System.out.println(seeded.nextInt(100));
}

// 生成随机流
DoubleStream randomDoubles = RandomGenerator.getDefault().doubles(1000);
randomDoubles.forEach(System.out::println);

// 查看所有可用的算法
RandomGenerator.all()
    .map(provider -> provider.name() + ": " + provider.group())
    .sorted()
    .forEach(System.out::println);

12. 虚拟线程(Virtual Threads):并发革命(JDK21)

// 创建和启动单个虚拟线程
Thread.startVirtualThread(() -> {
    System.out.println("Running in virtual thread");
});

// 使用虚拟线程运行多个任务
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    // 提交1000个任务,每个在独立的虚拟线程中运行
    for (int i = 0; i < 1000; i++) {
        int taskId = i;
        executor.submit(() -> {
            System.out.println("Task " + taskId + " running on " + Thread.currentThread());
            // 模拟IO操作
            try {
                Thread.sleep(Duration.ofMillis(100));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return taskId;
        });
    }
} // 自动关闭executor

// 以构建器方式创建虚拟线程
ThreadFactory factory = Thread.ofVirtual().name("worker-", 0).factory();
Thread worker = factory.newThread(() -> {
    // 任务代码
});
worker.start();

// 使用虚拟线程改写传统的阻塞式IO代码
void processFile(Path file) throws IOException {
    // 这段代码在虚拟线程中运行时不会阻塞平台线程
    try (var reader = Files.newBufferedReader(file)) {
        String line;
        while ((line = reader.readLine()) != null) {
            processLine(line);
        }
    }
}

13. Record模式(Record Patterns):解构数据更简单(JDK21)

// 定义一些记录
record Point(int x, int y) {}
record Rectangle(Point topLeft, Point bottomRight) {}
record Circle(Point center, int radius) {}

// 使用传统方式处理记录
Object shape = new Rectangle(new Point(1, 2), new Point(5, 6));
if (shape instanceof Rectangle) {
    Rectangle r = (Rectangle) shape;
    Point topLeft = r.topLeft();
    Point bottomRight = r.bottomRight();
    int width = bottomRight.x() - topLeft.x();
    int height = bottomRight.y() - topLeft.y();
    System.out.println("Rectangle with width " + width + " and height " + height);
}

// 使用Record模式解构
if (shape instanceof Rectangle(Point(var x1, var y1), Point(var x2, var y2))) {
    int width = x2 - x1;
    int height = y2 - y1;
    System.out.println("Rectangle with width " + width + " and height " + height);
}

// 结合switch使用
String getDescription(Object shape) {
    return switch (shape) {
        case Rectangle(Point(var x1, var y1), Point(var x2, var y2)) ->
            "Rectangle from (%d,%d) to (%d,%d)".formatted(x1, y1, x2, y2);
        
        case Circle(Point(var x, var y), var r) ->
            "Circle at (%d,%d) with radius %d".formatted(x, y, r);
        
        default -> "Unknown shape";
    };
}

14. 字符串模板(String Templates):安全高效的字符串插值(JDK21预览)

// 传统方式
String name = "Alice";
int age = 30;
String message = "Hello, " + name + "! Next year, you'll be " + (age + 1) + ".";

// 使用字符串模板
String message = STR."Hello, {name}! Next year, you'll be {age + 1}.";

// 带表达式的模板
String status = "active";
String message = STR."User status: {status.toUpperCase()} (set {LocalDate.now()})";

// 格式化数字
double value = 1234.56789;
String formatted = STR."The value is {value%.2f}";  // "The value is 1234.57"

// 多行JSON
String json = STR."""
    {
      "name": "{name}",
      "age": {age},
      "isAdult": {age >= 18},
      "contacts": [
        {generateContactsJson()}
      ]
    }
    """;

15. 序列集合 (Sequenced Collections):统一的集合操作(JDK21)

// 序列化集合基本用法
SequencedCollection<String> names = new ArrayList<>(List.of("Alice", "Bob", "Charlie"));

// 获取第一个和最后一个元素
String first = names.getFirst();  // "Alice"
String last = names.getLast();    // "Charlie"

// 添加元素到两端
names.addFirst("Zoe");
names.addLast("David");
System.out.println(names);  // [Zoe, Alice, Bob, Charlie, David]

// 创建反向视图
SequencedCollection<String> reversed = names.reversed();
System.out.println(reversed);  // [David, Charlie, Bob, Alice, Zoe]

// 序列化Map
SequencedMap<String, Integer> scores = new LinkedHashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 85);
scores.put("Charlie", 90);

// 获取第一个和最后一个条目
Map.Entry<String, Integer> firstEntry = scores.firstEntry();  // Alice=95
Map.Entry<String, Integer> lastEntry = scores.lastEntry();    // Charlie=90

// 添加条目到两端
scores.putFirst("Zoe", 100);
scores.putLast("David", 80);

// 获取键或值的序列化视图
SequencedCollection<String> keys = scores.sequencedKeySet();
SequencedCollection<Integer> values = scores.sequencedValues();
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]