本文目录导读:

我来为你提供几个Java链式调用的完整案例,从简单到复杂。
经典Builder模式(最常用)
import java.time.LocalDate;
// 用户实体类
public class User {
private final String name;
private final int age;
private final String email;
private final String phone;
private final String address;
private final LocalDate birthday;
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
this.phone = builder.phone;
this.address = builder.address;
this.birthday = builder.birthday;
}
// 静态工厂方法
public static Builder builder() {
return new Builder();
}
// 内部Builder类
public static class Builder {
private String name;
private int age;
private String email;
private String phone;
private String address;
private LocalDate birthday;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Builder birthday(LocalDate birthday) {
this.birthday = birthday;
return this;
}
public User build() {
// 可选:添加校验逻辑
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Name cannot be empty");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age is invalid");
}
return new User(this);
}
}
// Getters
public String getName() { return name; }
public int getAge() { return age; }
public String getEmail() { return email; }
public String getPhone() { return phone; }
public String getAddress() { return address; }
public LocalDate getBirthday() { return birthday; }
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + ", email='" + email + "'}";
}
}
// 使用示例
public class BuilderExample {
public static void main(String[] args) {
User user = User.builder()
.name("张三")
.age(25)
.email("zhangsan@example.com")
.phone("13800138000")
.address("北京市朝阳区")
.birthday(LocalDate.of(1998, 5, 20))
.build();
System.out.println(user);
// 也可以只设置部分字段
User partialUser = User.builder()
.name("李四")
.age(30)
.build();
System.out.println(partialUser);
}
}
Stream流式处理(函数式编程)
import java.util.*;
import java.util.stream.Collectors;
public class StreamChainExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("张三", 25, "北京"),
new Person("李四", 30, "上海"),
new Person("王五", 35, "广州"),
new Person("赵六", 20, "深圳"),
new Person("孙七", 28, "北京")
);
// 链式处理:过滤 -> 转换 -> 排序 -> 收集
List<String> result = people.stream()
.filter(p -> p.getAge() >= 25) // 过滤25岁以上
.filter(p -> p.getCity().equals("北京")) // 过滤北京
.map(Person::getName) // 提取姓名
.sorted() // 排序
.collect(Collectors.toList()); // 收集结果
System.out.println("北京25岁以上的人: " + result);
// 更复杂的链式操作
Map<String, Long> cityCount = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.counting()
));
System.out.println("城市人数统计: " + cityCount);
// 链式统计
double avgAge = people.stream()
.filter(p -> p.getAge() > 20)
.mapToInt(Person::getAge)
.average()
.orElse(0);
System.out.println("20岁以上平均年龄: " + avgAge);
}
}
class Person {
private String name;
private int age;
private String city;
public Person(String name, int age, String city) {
this.name = name;
this.age = age;
this.city = city;
}
public String getName() { return name; }
public int getAge() { return age; }
public String getCity() { return city; }
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", city='" + city + "'}";
}
}
字符串和集合操作链
public class UtilityChainExample {
public static void main(String[] args) {
// 字符串操作链
String text = " Hello World, Java Programming! ";
String result = text.trim()
.toLowerCase()
.replace("java", "Python")
.replaceAll("\\s+", " ")
.substring(0, 20)
+ "...";
System.out.println("字符串处理: " + result);
// List操作链
List<Integer> numbers = Arrays.asList(5, 3, 8, 1, 9, 2, 7, 4, 6);
// 链式过滤、排序、转换
List<Integer> processed = numbers.stream()
.filter(n -> n % 2 == 0) // 保留偶数
.map(n -> n * n) // 平方
.sorted(Comparator.reverseOrder()) // 降序排列
.limit(3) // 取前3个
.collect(Collectors.toList());
System.out.println("数字处理: " + processed);
// 使用Optional链
String email = Optional.ofNullable(null)
.map(Object::toString)
.orElseGet(() -> "default@email.com");
System.out.println("Optional处理: " + email);
}
}
自定义链式查询类(SQL风格)
import java.util.*;
import java.util.stream.Collectors;
public class QueryBuilder<T> {
private final Collection<T> data;
private List<Predicate<T>> predicates = new ArrayList<>();
private Comparator<T> comparator;
private int limit = Integer.MAX_VALUE;
private QueryBuilder(Collection<T> data) {
this.data = new ArrayList<>(data);
}
public static <T> QueryBuilder<T> from(Collection<T> data) {
return new QueryBuilder<>(data);
}
public QueryBuilder<T> where(Predicate<T> predicate) {
this.predicates.add(predicate);
return this;
}
public QueryBuilder<T> orderBy(Comparator<T> comparator) {
this.comparator = comparator;
return this;
}
public QueryBuilder<T> limit(int n) {
this.limit = n;
return this;
}
public List<T> execute() {
List<T> stream = this.data.stream()
.filter(item -> predicates.stream().allMatch(p -> p.test(item)))
.collect(Collectors.toList());
if (comparator != null) {
stream.sort(comparator);
}
return stream.stream()
.limit(limit)
.collect(Collectors.toList());
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
}
// 实体类
class Product {
private String name;
private double price;
private String category;
public Product(String name, double price, String category) {
this.name = name;
this.price = price;
this.category = category;
}
public String getName() { return name; }
public double getPrice() { return price; }
public String getCategory() { return category; }
@Override
public String toString() {
return "Product{name='" + name + "', price=" + price + ", category='" + category + "'}";
}
}
// 使用示例
public class QueryBuilderExample {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("iPhone", 5999, "手机"),
new Product("MacBook", 12999, "电脑"),
new Product("AirPods", 1999, "配件"),
new Product("iPhone Pro", 8999, "手机"),
new Product("iPad", 3999, "平板")
);
// 流畅的查询API
List<Product> results = QueryBuilder.from(products)
.where(p -> p.getPrice() > 3000) // 价格大于3000
.where(p -> p.getCategory().equals("手机")) // 手机类别
.orderBy(Comparator.comparing(Product::getPrice).reversed()) // 按价格降序
.limit(2) // 取前2条
.execute();
System.out.println("查询结果: " + results);
}
}
Spring WebFlux/Reactive风格
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;
import java.time.Duration;
import java.util.Arrays;
public class ReactiveChainExample {
public static void main(String[] args) {
// Reactive Streams 链式操作(需要引入reactor-core依赖)
Flux.just(1, 2, 3, 4, 5)
.map(i -> i * 10) // 乘以10
.filter(i -> i > 20) // 过滤大于20
.defaultIfEmpty(100) // 如果没有数据返回默认值
.subscribe(System.out::println);
System.out.println("---");
// 组合多个数据源
Flux<String> names = Flux.just("张三", "李四", "王五");
Flux<Integer> ages = Flux.just(25, 30, 35);
names.zipWith(ages, (name, age) -> name + " - " + age + "岁")
.subscribe(System.out::println);
}
}
最佳实践建议
- 命名清晰:链式方法名要清晰表达功能
- 不可变性:每次调用返回新对象,不修改原对象
- 参数校验:在最后build/execute时做校验
- 错误处理:提供合理的异常信息
- IDE支持:链式调用便于IDE自动补全
实际应用场景
// 在Spring Boot中常见用法
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
public Order buildOrder() {
return Order.builder()
.userId(12345L)
.totalAmount(999.99)
.status(OrderStatus.PENDING)
.items(Arrays.asList(
new OrderItem("iPhone 15", 5999, 1),
new OrderItem("AirPods Pro", 1899, 2)
))
.shippingAddress("北京市朝阳区xx路xx号")
.build();
}
public void processOrders() {
orderRepository.findAll()
.stream()
.filter(o -> o.getStatus() == OrderStatus.PENDING)
.map(this::convertToDTO)
.collect(Collectors.toList());
}
}
这些案例展示了Java中链式调用的不同实现方式和应用场景,选择哪种方式取决于你的具体需求:Builder模式适合对象创建,Stream适合集合处理,自定义QueryBuilder适合领域特定查询。