生产型接口Supplier
简述
该函数接口是Java8中的java.util.function
包中的。包含一个get()
作用
-
延迟计算:
在需要时才生成值,提高效率。 -
简化代码:
封装生成逻辑,避免重复代码。 -
灵活性:
可以与其他函数式接口结合使用,增强可组合性。 -
无输入参数:
专注于提供结果,适用于无状态的生成逻辑。
代码案例
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.function.Supplier;
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + "}";
}
}
public class SupplierFeaturesExample {
private static final String[] NAMES = {"Alice", "Bob", "Charlie", "Diana", "Eve"};
private static final Random RANDOM = new Random();
public static void main(String[] args) {
// Supplier 用于生成随机用户
Supplier<User> userSupplier = () -> {
String name = NAMES[RANDOM.nextInt(NAMES.length)];
int age = RANDOM.nextInt(50) + 18; // 生成 18 到 67 之间的随机年龄
return new User(name, age);
};
// 延迟计算:用户信息在需要时才生成
List<User> userList = new ArrayList<>();
System.out.println("Generating random users...");
for (int i = 0; i < 5; i++) {
// 每次调用 userSupplier.get() 都会生成一个新的随机用户
User user = userSupplier.get();
userList.add(user);
System.out.println("Generated user: " + user);
}
// 使用 Supplier 生成用户的另一种方式:将 Supplier 作为参数传递
List<User> moreUsers = generateUsers(() -> {
String name = NAMES[RANDOM.nextInt(NAMES.length)];
int age = RANDOM.nextInt(50) + 18;
return new User(name, age);
}, 5);
System.out.println("\nAdditional generated users:");
moreUsers.forEach(System.out::println);
}
// 接受 Supplier 的方法,生成指定数量的用户
private static List<User> generateUsers(Supplier<User> userSupplier, int count) {
List<User> users = new ArrayList<>();
for (int i = 0; i < count; i++) {
users.add(userSupplier.get());
}
return users;
}
}
消费型接口Consumer
简述
Consumer 接口是 Java 8
引入的一个函数式接口,位于 java.util.function
包中。它代表一个接受单个输入参数并且没有返回结果的操作。Consumer 通常用于处理某种类型的对象,比如打印、修改或存储数据。
作用
-
处理数据:
Consumer 可以用于对单个输入数据进行处理,如打印、修改或存储。这使得数据处理逻辑能够被清晰地定义。 -
简化代码:
通过使用 Consumer,可以减少样板代码,使得操作更加简洁。例如,可以直接在集合的forEach
方法中传入 Consumer 实现,从而避免显式的循环。 -
函数式编程支持:
Consumer 支持函数式编程风格,使得开发者能够以更灵活的方式组合和传递行为。例如,可以将多个 Consumer 组合在一起,通过andThen
方法实现链式调用。 -
事件处理:
在事件驱动编程中,Consumer 可以用于处理用户输入或其他事件,提供了一种清晰的方式来定义事件处理逻辑。 -
增强可读性:
使用 Consumer 可以使代码逻辑更加清晰易懂,特别是在进行集合操作时,能让操作意图一目了然。
代码案例
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 定义一个 Consumer,打印每个名字
Consumer<String> printName = name -> System.out.println(name);
// 使用 forEach 方法与 Consumer
names.forEach(printName);
// 使用 andThen 方法,打印名字并附加额外操作
names.forEach(printName.andThen(name -> System.out.println("Length: " + name.length())));
}
}
判断型接口Predicate
简述
Predicate 接口是 Java 8
引入的一个函数式接口,属于 java.util.function
包。它用于测试输入值是否满足某种条件,并返回一个布尔值。Predicate 主要用于过滤和判断操作
作用
-
过滤集合:
在处理集合数据时,可以使用 Predicate 进行条件过滤。 -
条件判断:
可以使用 Predicate 来判断对象是否符合某些条件,用于实现业务逻辑。 -
流操作:
在 Java Streams API 中,Predicate 被广泛用于过滤流中的元素。
代码案例
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class PredicateExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 定义一个 Predicate,判断名字是否以字母 'A' 开头
Predicate<String> startsWithA = name -> name.startsWith("A");
// 过滤集合中符合条件的名字
List<String> filteredNames = names.stream()
.filter(startsWithA)
.collect(Collectors.toList());
System.out.println(filteredNames); // 输出: [Alice]
// 使用 and 方法,判断名字是否以字母 'A' 开头并且长度大于 3
Predicate<String> startsWithAAndLongerThan3 = startsWithA.and(name -> name.length() > 3);
filteredNames = names.stream()
.filter(startsWithAAndLongerThan3)
.collect(Collectors.toList());
System.out.println(filteredNames); // 输出: [Alice]
// 使用 or 方法,判断名字是否以字母 'A' 开头或名字长度大于 5
Predicate<String> startsWithAOrLongerThan5 = startsWithA.or(name -> name.length() > 5);
filteredNames = names.stream()
.filter(startsWithAOrLongerThan5)
.collect(Collectors.toList());
System.out.println(filteredNames); // 输出: [Alice, Charlie]
// 使用 negate 方法,判断名字是否不以字母 'A' 开头
Predicate<String> notStartsWithA = startsWithA.negate();
filteredNames = names.stream()
.filter(notStartsWithA)
.collect(Collectors.toList());
System.out.println(filteredNames); // 输出: [Bob, Charlie, David]
}
}
转换型接口Function
简述
Function 接口是 Java 8 引入的一个函数式接口,属于 java.util.function
包。它代表了一个接受一个输入参数并生成一个输出结果的函数。Function 接口的主要作用是将一个输入值转换成另一个值,因此常用于数据转换和映射操作中。
作用
-
数据转换:
用于将数据从一种形式转换为另一种形式。 -
集合操作:
在处理集合数据时,可以使用 Function 来映射集合中的元素。 -
流操作:
在 Java Streams API 中,Function 被广泛用于将流中的元素映射到另一个形式。
代码案例
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class FunctionExample {
public static void main(String[] args) {
// 定义一个 Function,将字符串转换为其长度
Function<String, Integer> stringLengthFunction = String::length;
// 使用 Function 计算每个名字的长度
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<Integer> nameLengths = names.stream()
.map(stringLengthFunction)
.collect(Collectors.toList());
System.out.println(nameLengths); // 输出: [5, 3, 7, 5]
// 定义一个 Function,将整数转换为其平方
Function<Integer, Integer> squareFunction = x -> x * x;
// 组合两个 Function:首先计算字符串的长度,然后计算长度的平方
Function<String, Integer> lengthSquaredFunction = stringLengthFunction.andThen(squareFunction);
List<Integer> lengthSquares = names.stream()
.map(lengthSquaredFunction)
.collect(Collectors.toList());
System.out.println(lengthSquares); // 输出: [25, 9, 49, 25]
// 组合两个 Function:首先计算字符串的长度,然后计算长度加 1
Function<String, Integer> lengthPlusOneFunction = stringLengthFunction.compose(x -> x + "X");
List<Integer> lengthPlusOne = names.stream()
.map(lengthPlusOneFunction)
.collect(Collectors.toList());
System.out.println(lengthPlusOne); // 输出: [6, 4, 8, 6]
}
}
标签:Function,常用,java,函数,List,接口,util,import,name
From: https://www.cnblogs.com/dragon-925/p/18363116