Java 进阶特性集锦--流操作、Optional和函数式编程等

发布时间:2024年01月11日

Java 8 引入了许多新特性,这些特性极大地改善了开发者的编程体验和代码的简洁性。下面是一些Java 8开发中的进阶语法特性以及相应的案例代码:

  1. Lambda 表达式
    Lambda 表达式允许你以匿名函数的形式来表示接口的实例,这对于编写简洁的代码非常有用,特别是当使用函数式接口时。

    // 使用lambda表达式替代匿名类
    List<String> names = Arrays.asList("John", "Jane", "Doe");
    Collections.sort(names, (String a, String b) -> {
        return b.compareTo(a);
    });
    
  2. Stream API
    Stream API 是Java 8中引入的一组用于操作数据源(如集合)的高级迭代器。它提供了一种声明式的方式来处理数据。

    // 使用Stream API来过滤、排序和打印列表中的元素
    names.stream()
         .filter(s -> s.startsWith("J"))
         .sorted()
         .forEach(System.out::println);
    
  3. 方法引用
    方法引用提供了一种引用方法而不执行它的方式。方法引用可以使你的代码更简洁、更清晰。

    // 使用方法引用代替lambda表达式
    names.forEach(System.out::println);
    
  4. Optional 类
    Optional 类是一个容器对象,它可以包含也可以不包含非空值。这个类的引入是为了避免null导致的问题。

    // 使用Optional来避免NullPointerException
    Optional<String> optionalName = names.stream().filter(s -> s.startsWith("J")).findFirst();
    optionalName.ifPresent(name -> System.out.println("Found: " + name));
    
  5. 接口中的默认方法和静态方法
    Java 8 允许在接口中包含具有默认实现的方法和静态方法,这提供了更大的灵活性。

    interface Vehicle {
        default void print() {
            System.out.println("I am a vehicle!");
        }
        
        static void blowHorn() {
            System.out.println("Blowing horn!!!");
        }
    }
    
  6. 新的日期时间 API (java.time)
    Java 8 引入了全新的日期时间API,它比老的DateCalendar类更强大、更易于使用。

    // 使用新的日期时间API
    LocalDate today = LocalDate.now();
    LocalTime now = LocalTime.now();
    LocalDateTime dateTime = LocalDateTime.of(today, now);
    
    System.out.println("Today's Date: " + today);
    System.out.println("Current Time: " + now);
    System.out.println("Current DateTime: " + dateTime);
    
  7. CompletableFuture
    CompletableFuture 是异步编程的一种方式,它在Future的基础上提供了更多的功能和灵活性。

    // 使用CompletableFuture来异步执行任务
    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "Result of the asynchronous computation";
    });
    
    // 等待异步操作完成并获取结果
    String result = future.get(); // 阻塞直到结果可用
    System.out.println(result);
    
  8. 集合框架的增强
    Java 8为集合框架增加了新的方法,特别是对ListMapSet接口的增强。

    // 使用Map的新方法getOrDefault
    Map<String, Integer> nameMap = new HashMap<>();
    Integer value = nameMap.getOrDefault("John", 0);
    System.out.println(value); // 输出0,因为"John"并不在map中
    
    // 使用Map的新方法putIfAbsent
    nameMap.putIfAbsent("John", 1);
    System.out.println(nameMap.get("John")); // 输出1
    
    // 使用Map的新方法forEach
    nameMap.forEach((key, val) -> System.out.println(key + " -> " + val));
    
  9. 并行Streams
    Java 8引入了并行流,它可以利用多核处理器的优势来加速数据处理。

    // 并行处理集合元素
    int sum = names.parallelStream()
                   .filter(s -> s.startsWith("J"))
                   .mapToInt(String::length)
                   .sum();
    System.out.println("Total length of all names starting with 'J': " + sum);
    
  10. Collectors
    Collectors类提供了一系列用于处理Stream中数据的方法,可用于返回列表、字符串、甚至是数据分组。

    // 使用Collectors来收集数据
    List<String> filteredNames = names.stream()
                                      .filter(s -> s.startsWith("J"))
                                      .collect(Collectors.toList());
    
    // 使用Collectors.joining()来连接字符串
    String joined = names.stream()
                         .filter(s -> s.startsWith("J"))
                         .collect(Collectors.joining(", "));
    System.out.println("Joined names: " + joined);
    
    // 使用Collectors.groupingBy()进行分组
    Map<Character, List<String>> groupedByName = names.stream()
                                                      .collect(Collectors.groupingBy(s -> s.charAt(0)));
    System.out.println(groupedByName);
    
  11. 类型推断的增强
    Java 8引入了<>操作符,也被称为"钻石操作符",可以与匿名内部类一起使用,在某些情况下增强了类型推断的能力。

    // Java 7之前必须在构造器后重复泛型类型
    Map<String, List<String>> myMap = new HashMap<String, List<String>>();
    
    // Java 8中可以省略构造器后的泛型类型
    Map<String, List<String>> myMap8 = new HashMap<>();
    
  12. Functional Interface
    Java 8在java.util.function包中引入了一系列的函数式接口,比如PredicateConsumerFunction等。

    // 使用Predicate函数式接口
    Predicate<String> startsWithJ = (n) -> n.startsWith("J");
    boolean isStartingWithJ = startsWithJ.test("John");
    System.out.println("Does 'John' start with 'J'? " + isStartingWithJ);
    
    // 使用Function函数式接口
    Function<String, Integer> nameLength = String::length;
    int length = nameLength.apply("John");
    System.out.println("Length of 'John': " + length);
    
  13. 接口的默认方法:
    Java 8允许在接口中定义默认方法,这些方法可以有自己的实现,而且不强制实现类覆盖它们。

    interface MyInterface {
        default void defaultMethod() {
            System.out.println("This is a default method");
        }
        
        void abstractMethod();
    }
    
    class MyClass implements MyInterface {
        public void abstractMethod() {
            System.out.println("Abstract method implementation");
        }
    }
    
    MyInterface obj = new MyClass();
    obj.defaultMethod(); // 输出: This is a default method
    obj.abstractMethod(); // 输出: Abstract method implementation
    
  14. 接口的静态方法:
    Java 8允许在接口中定义静态方法,这些方法可以直接通过接口调用。

    interface MyInterface {
        static void staticMethod() {
            System.out.println("This is a static method in an interface");
        }
    }
    
    MyInterface.staticMethod(); // 输出: This is a static method in an interface
    
  15. @FunctionalInterface 注解:
    @FunctionalInterface注解用于指示某个接口满足函数式接口的条件,即只有一个抽象方法的接口。

    @FunctionalInterface
    interface MyFunctionalInterface {
        void execute();
    }
    
    MyFunctionalInterface fi = () -> System.out.println("Running execute()");
    fi.execute(); // 输出: Running execute()
    
  16. Java 8 新的数学函数:
    Java 8在Math类中加入了新的数学函数,比如floorDivfloorMod等。

    int result = Math.floorDiv(7, 3); // result -> 2
    System.out.println(result);
    
  17. 新的Nashorn JavaScript引擎:
    Java 8引入了新的Nashorn JavaScript引擎,允许在JVM上运行JavaScript代码。

    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
    ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
    
    String code = "print('Hello Nashorn');";
    nashorn.eval(code); // 输出: Hello Nashorn
    
  18. 新的网络功能:
    Java 8增加了对HTTP/2协议的支持,并且引入了新的HTTP Client API。

    // Java 11中引入的HttpClient,但Java 8中有HttpURLConnection等类可以使用
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
                                     .uri(URI.create("http://example.com"))
                                     .build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body());
    
  19. Base64编码API:
    Java 8引入了新的Base64编码和解码的API。

    String originalInput = "test input";
    String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
    
    byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
    String decodedString = new String(decodedBytes);
    
    System.out.println(encodedString); // 输出编码后的字符串
    System.out.println(decodedString); // 输出原始输入字符串
    
  20. Type Annotations:
    Java 8引入了对类型注解的支持,这允许你在任何使用类型的地方使用注解,例如在类型声明、类型转换、泛型和实现接口中。

    // 使用类型注解来实现非空检查
    public class NonNullExample {
        public void myMethod(@NonNull String str) {
            System.out.println(str);
        }
    }
    
  21. 重复注解:
    在Java 8之前,一个位置上不能声明多个相同类型的注解。Java 8引入的@Repeatable注解允许在同一个声明上使用多次同一个注解。

    // 假设有一个可重复注解Hint
    @Repeatable(Hints.class)
    @interface Hint {
        String value();
    }
    
    // 容器注解
    @interface Hints {
        Hint[] value();
    }
    
    // 使用重复注解
    @Hint("hint1")
    @Hint("hint2")
    class Person {}
    
  22. 参数名称:
    Java 8允许你通过反射访问方法和构造函数参数的名称,但需要在编译时使用-parameters选项。

    // 编译时要加上-parameters选项来保留参数名信息
    public class ParameterNamesExample {
        public void myMethod(String greeting, int count) {
            // 方法体
        }
    }
    // 反射获取参数名
    Method method = ParameterNamesExample.class.getMethod("myMethod", String.class, int.class);
    Parameter[] parameters = method.getParameters();
    String parameterName1 = parameters[0].getName(); // greeting
    String parameterName2 = parameters[1].getName(); // count
    
  23. 并发改进:
    Java 8对并发编程进行了改进,特别是在ConcurrentHashMap类和CompletableFuture类中。

    // ConcurrentHashMap的新方法
    ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
    map.put("A", 1);
    map.computeIfAbsent("B", key -> 2);
    map.computeIfPresent("A", (key, val) -> val + 2);
    
    // CompletableFuture的组合使用
    CompletableFuture<String> future1
      = CompletableFuture.supplyAsync(() -> "Hello");
    CompletableFuture<String> future2
      = CompletableFuture.supplyAsync(() -> "World");
    CompletableFuture<String> combinedFuture
      = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2);
    
    String combined = combinedFuture.get(); // Hello World
    
  24. IO/NIO 改进:
    Java 8引入了对文件系统事件的监听器WatchService,并且对文件I/O进行了一些改进,比如Files类中的新方法。

    // 使用Files类中的新方法
    Path path = Paths.get("example.txt");
    List<String> fileLines = Files.readAllLines(path, StandardCharsets.UTF_8);
    Files.write(path, fileLines, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
    
  25. JDBC 4.2:
    Java 8更新了JDBC API,包括对REF_CURSOR类型的支持,以及改进了日期和时间的处理。

    // JDBC中使用新的日期时间API
    try (Connection connection = DriverManager.getConnection(url, username, password)) {
        String sql = "SELECT * FROM events WHERE date > ?";
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setObject(1, LocalDate.now());
            try (ResultSet resultSet = statement.executeQuery()) {
                while (resultSet.next()) {
                    // 处理结果集
                }
            }
        }
    }
    
文章来源:https://blog.csdn.net/sinat_41883985/article/details/135496084
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。