Java函数式编程常用案例学习

一、Optional API

1. 创建Optional实例

1.1 空Optional

1
2
Optional<String> emptyOpt = Optional.empty();
// 创建一个空的Optional对象,不包含任何值

1.2 非null值的Optional

1
2
3
String str = "Hello";
Optional<String> nonNullOpt = Optional.of(str);
// 当str为null时会抛出NullPointerException

1.3 可能为null的Optional

1
2
3
String str = null;
Optional<String> nullableOpt = Optional.ofNullable(str);
// 安全处理可能为null的值,不会抛出异常

2. 判断值是否存在

2.1 判断值存在

1
2
3
4
Optional<String> opt = Optional.of("Hello");
if (opt.isPresent()) {
System.out.println(opt.get()); // 输出: Hello
}

2.2 判断值不存在(Java 11+)

1
2
3
4
Optional<String> opt = Optional.empty();
if (opt.isEmpty()) {
System.out.println("值不存在"); // 输出: 值不存在
}

3. 获取值

3.1 直接获取值

1
2
Optional<String> opt = Optional.of("Hello");
String value = opt.get(); // 当值不存在时抛出NoSuchElementException

3.2 默认值获取(orElse)

1
2
Optional<String> opt = Optional.empty();
String value = opt.orElse("默认值"); // 输出: 默认值

3.3 延迟加载默认值(orElseGet)

1
2
Optional<String> opt = Optional.empty();
String value = opt.orElseGet(() -> "延迟生成的默认值"); // 输出: 延迟生成的默认值

3.4 值不存在时抛出异常(orElseThrow)

1
2
Optional<String> opt = Optional.empty();
String value = opt.orElseThrow(() -> new IllegalArgumentException("值不存在"));

4. 条件操作

4.1 值存在时执行操作

1
2
Optional<String> opt = Optional.of("Hello");
opt.ifPresent(System.out::println); // 输出: Hello

4.2 值存在或不存在时执行不同操作(Java 9+)

1
2
3
4
5
Optional<String> opt = Optional.empty();
opt.ifPresentOrElse(
System.out::println,
() -> System.out.println("值不存在") // 输出: 值不存在
);

5. 过滤和映射

5.1 过滤值

1
2
3
Optional<String> opt = Optional.of("Hello World");
opt.filter(s -> s.contains("World"))
.ifPresent(System.out::println); // 输出: Hello World

5.2 映射值

1
2
3
Optional<String> opt = Optional.of("hello");
opt.map(String::toUpperCase)
.ifPresent(System.out::println); // 输出: HELLO

5.3 扁平映射

1
2
3
Optional<String> opt = Optional.of("hello");
Optional<Integer> lengthOpt = opt.flatMap(s -> Optional.of(s.length()));
lengthOpt.ifPresent(System.out::println); // 输出: 5

二、Stream API

1. 创建流

1.1 从集合创建流

1
2
3
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 串行流
Stream<String> parallelStream = list.parallelStream(); // 并行流

1.2 从数组创建流

1
2
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

1.3 创建指定元素的流

1
Stream<String> stream = Stream.of("a", "b", "c");

2. 中间操作

2.1 过滤(filter)

1
2
3
4
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(n -> n % 2 == 0) // 保留偶数
.forEach(System.out::println); // 输出: 2 4

2.2 映射(map)

1
2
3
4
List<String> words = Arrays.asList("hello", "world");
words.stream()
.map(String::length) // 转换为字符串长度
.forEach(System.out::println); // 输出: 5 5

2.3 排序(sorted)

1
2
3
4
5
6
7
8
List<Integer> numbers = Arrays.asList(3, 1, 2);
numbers.stream()
.sorted() // 自然排序
.forEach(System.out::println); // 输出: 1 2 3

numbers.stream()
.sorted(Collections.reverseOrder()) // 降序排序
.forEach(System.out::println); // 输出: 3 2 1

2.4 去重(distinct)

1
2
3
4
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
numbers.stream()
.distinct() // 去重
.forEach(System.out::println); // 输出: 1 2 3

2.5 限制数量(limit)和跳过元素(skip)

1
2
3
4
5
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.skip(2) // 跳过前2个元素
.limit(2) // 取2个元素
.forEach(System.out::println); // 输出: 3 4

3. 终端操作

3.1 遍历(forEach)

1
2
List<String> list = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println); // 输出: a b c

3.2 收集结果(collect)

1
2
3
4
List<String> list = Arrays.asList("a", "b", "c");
List<String> upperList = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // 结果: ["A", "B", "C"]

3.3 计数(count)

1
2
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count(); // 结果: 5

3.4 匹配(anyMatch, allMatch, noneMatch)

1
2
3
4
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0); // true
boolean allPositive = numbers.stream().allMatch(n -> n > 0); // true
boolean noNegative = numbers.stream().noneMatch(n -> n < 0); // true

3.5 查找(findFirst, findAny)

1
2
3
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> first = numbers.stream().findFirst(); // 1
Optional<Integer> any = numbers.parallelStream().findAny(); // 可能为任意元素

4. 收集器应用

4.1 分组(groupingBy)

1
2
3
4
List<String> words = Arrays.asList("apple", "banana", "cat", "dog");
Map<Integer, List<String>> groupByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// 结果: {3=["cat", "dog"], 5=["apple"], 6=["banana"]}

4.2 字符串拼接(joining)

1
2
3
4
List<String> words = Arrays.asList("Hello", "World");
String joined = words.stream()
.collect(Collectors.joining(" ", "Prefix: ", " Suffix"));
// 结果: "Prefix: Hello World Suffix"

4.3 汇总统计(summarizingInt)

1
2
3
4
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
IntSummaryStatistics stats = numbers.stream()
.collect(Collectors.summarizingInt(Integer::intValue));
// stats包含: count=5, sum=15, min=1, max=5, average=3.0

三、函数式编程

1. Lambda表达式基础

1.1 无参数无返回值

1
2
Runnable runnable = () -> System.out.println("Hello Lambda");
new Thread(runnable).start(); // 输出: Hello Lambda

1.2 单参数

1
2
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello"); // 输出: Hello

1.3 多参数和返回值

1
2
BinaryOperator<Integer> adder = (a, b) -> a + b;
int sum = adder.apply(3, 5); // 结果: 8

2. 函数式接口

2.1 Predicate(断言)

1
2
Predicate<Integer> isPositive = n -> n > 0;
boolean result = isPositive.test(5); // true

2.2 Function(函数)

1
2
Function<String, Integer> strLength = s -> s.length();
int length = strLength.apply("Hello"); // 5

2.3 Consumer(消费者)

1
2
Consumer<String> logger = s -> System.out.println("Log: " + s);
logger.accept("System started"); // 输出: Log: System started

2.4 Supplier(供应商)

1
2
Supplier<Double> randomValue = () -> Math.random();
double value = randomValue.get(); // 生成随机数

3. 方法引用

3.1 静态方法引用

1
2
Function<String, Integer> parseInt = Integer::parseInt;
int number = parseInt.apply("123"); // 123

3.2 实例方法引用

1
2
3
String str = "Hello";
Supplier<Integer> lengthSupplier = str::length;
int length = lengthSupplier.get(); // 5

3.3 类的任意对象的方法引用

1
2
Function<String, String> toUpperCase = String::toUpperCase;
String upper = toUpperCase.apply("hello"); // "HELLO"

3.4 构造函数引用

1
2
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> list = listSupplier.get(); // 创建新ArrayList

4. 函数组合

4.1 函数链(andThen)

1
2
3
4
5
Function<Integer, Integer> add5 = x -> x + 5;
Function<Integer, Integer> multiply2 = x -> x * 2;

Function<Integer, Integer> add5ThenMultiply2 = add5.andThen(multiply2);
int result = add5ThenMultiply2.apply(3); // (3+5)*2=16

4.2 函数组合(compose)

1
2
3
4
5
Function<Integer, Integer> add5 = x -> x + 5;
Function<Integer, Integer> multiply2 = x -> x * 2;

Function<Integer, Integer> multiply2ThenAdd5 = add5.compose(multiply2);
int result = multiply2ThenAdd5.apply(3); // (3*2)+5=11

4.3 谓词组合(and, or, negate)

1
2
3
4
5
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isGreaterThan5 = n -> n > 5;

Predicate<Integer> isEvenAndGreaterThan5 = isEven.and(isGreaterThan5);
boolean result = isEvenAndGreaterThan5.test(6); // true

5. 变量作用域

5.1 访问外部变量(effectively final)

1
2
3
4
int num = 10; // 隐式final
Consumer<Integer> consumer = x -> System.out.println(x + num);
consumer.accept(5); // 输出: 15
// num = 20; // 编译错误,不能修改

5.2 线程安全的Lambda

1
2
3
4
5
6
7
List<Integer> list = new ArrayList<>();
IntStream.range(0, 10).forEach(i -> {
// 访问非线程安全集合需要同步
synchronized (list) {
list.add(i);
}
});