在JDK中,你能找到哪些策略模式的实际应用案例?请举例说明。

参考回答

问题:在JDK中,你能找到哪些策略模式的实际应用案例?请举例说明。

在JDK中,有很多地方都运用了策略模式,尤其是在集合框架和排序等场景中。最常见的应用案例包括Comparator接口的使用和Collections.sort()方法。

详细讲解与拓展

1. ComparatorCollections.sort()

Comparator接口和Collections.sort()方法是JDK中典型的策略模式应用。Comparator用于定义排序算法,而Collections.sort()方法通过传入不同的Comparator对象来实现灵活的排序策略切换。

具体应用:
  • 策略接口Comparator接口,它定义了一个compare()方法,用于比较两个对象的大小。
  • 具体策略类:实现Comparator接口的具体类(例如:Comparator<Integer>Comparator<String>等),每个策略类实现不同的比较方式。
  • 上下文类Collections.sort()方法,作为上下文类,它接收一个Comparator对象,并通过调用该对象的compare()方法来对集合进行排序。
代码示例:
import java.util.*;

public class StrategyPatternInJDK {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(5, 3, 7, 1, 9, 2);

        // 按升序排序
        Collections.sort(numbers, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;  // 升序
            }
        });
        System.out.println("升序排序: " + numbers);

        // 按降序排序
        Collections.sort(numbers, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;  // 降序
            }
        });
        System.out.println("降序排序: " + numbers);
    }
}
Java
工作原理
  • Comparator是策略模式中的策略接口,它定义了比较算法(即排序规则)。
  • Collections.sort()方法充当上下文类,根据传入的Comparator对象执行不同的排序策略。
  • 当我们传入不同的Comparator实现时,Collections.sort()就会按不同的方式进行排序。这使得排序行为是可配置的,并且可以在运行时灵活切换。

2. ThreadPoolExecutor的策略模式应用

ThreadPoolExecutor类中的RejectedExecutionHandler接口也是策略模式的一个应用。在ThreadPoolExecutor中,当线程池中的任务队列已满,无法接受新的任务时,它会通过RejectedExecutionHandler接口的实现来处理被拒绝的任务。

具体应用:
  • 策略接口RejectedExecutionHandler接口,用于定义当任务被拒绝时的处理策略。
  • 具体策略类:例如,AbortPolicy(抛出异常)、CallerRunsPolicy(由提交任务的线程自己执行任务)等。
  • 上下文类ThreadPoolExecutor类,根据具体的拒绝策略执行不同的任务拒绝处理方式。
代码示例:
import java.util.concurrent.*;

public class ThreadPoolExecutorStrategyExample {
    public static void main(String[] args) {
        // 创建一个核心线程数为2,最大线程数为4,任务队列大小为2的线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(2), new ThreadPoolExecutor.AbortPolicy()); // 使用AbortPolicy策略

        for (int i = 0; i < 6; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Executing task " + taskId);
            });
        }

        executor.shutdown();
    }
}
Java
工作原理
  • RejectedExecutionHandler是一个策略接口,定义了当线程池任务被拒绝时的处理方式。
  • ThreadPoolExecutor通过传入不同的RejectedExecutionHandler策略来决定如何处理拒绝的任务。
  • 例如,AbortPolicy策略会直接抛出RejectedExecutionException异常,而CallerRunsPolicy策略则会让提交任务的线程自己去执行该任务。

3. java.util.stream中的Collector

在Java 8的Stream API中,Collector接口也是策略模式的一种应用。Collector用于定义如何将流中的元素累积成一个结果(比如:List、Set、Map、String等)。

具体应用:
  • 策略接口Collector接口,定义了如何对流中的元素进行收集。
  • 具体策略类:例如:Collectors.toList()Collectors.joining()Collectors.groupingBy()等。
  • 上下文类Stream.collect()方法,根据传入的Collector实现来对流中的元素进行不同的操作(例如:收集成一个List,或将元素拼接成一个String)。
代码示例:
import java.util.*;
import java.util.stream.*;

public class StreamCollectorStrategyExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        // 使用不同的策略(Collector)收集流中的元素
        List<String> list = names.stream()
                                 .collect(Collectors.toList()); // 使用toList策略
        System.out.println("List: " + list);

        String result = names.stream()
                             .collect(Collectors.joining(", ")); // 使用joining策略
        System.out.println("Joined: " + result);

        Map<Integer, List<String>> grouped = names.stream()
                                                  .collect(Collectors.groupingBy(String::length)); // 使用groupingBy策略
        System.out.println("Grouped: " + grouped);
    }
}
Java
工作原理
  • Collector接口定义了如何对流中的元素进行累积操作。
  • Stream.collect()方法根据传入的Collector实现来进行不同的收集操作(如将元素收集到ListMap,或将字符串连接成一个大字符串等)。
  • 这种方式符合策略模式的思想,策略(即收集方法)被封装在Collector对象中,Stream通过调用collect()方法灵活地使用不同的策略来处理流中的元素。

总结

在JDK中,策略模式的应用非常广泛,尤其是在集合类、线程池、流操作等方面。通过策略模式,JDK能够为开发者提供灵活的操作方式,不同的策略(算法或行为)可以在运行时进行选择和切换,增强了系统的可扩展性和灵活性。例如,Comparator接口用于排序的策略、ThreadPoolExecutor中的拒绝策略以及Stream中的收集策略,都是策略模式的实际应用案例。

发表评论

后才能评论