1.用Function封装类型转换逻辑 在数据处理中,类型转换是高频操作。
重复编写转换代码不仅冗余,还会增加维护成本。借助Function,我们可将转换逻辑封装为独立组件,实现一次定义、多处复用。
import java.util.function.Function; public class TypeConversion { // 定义String转Integer的Function,处理可能的转换异常 public static final Function<String, Integer> STRING_TO_INTEGER = str -> { if (str == null || str.isEmpty()) { // 检查输入是否为空 return 0; // 空值时返回默认值 } try { return Integer.parseInt(str); // 执行转换 } catch (NumberFormatException e) { return 0; // 转换失败时返回默认值 } }; public static void main(String[] args) { String numStr = "123"; Integer num = STRING_TO_INTEGER.apply(numStr); // 应用转换逻辑 System.out.println(num); // 输出:123 } }代码解析:通过定义静态Function常量STRING_TO_INTEGER,我们将String到Integer的转换逻辑(包括空值处理和异常捕获)封装其中。在main方法中,只需调用apply方法即可完成转换,无需重复编写校验与转换代码。
import java.util.Arrays; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; public class StreamWithFunction { public static void main(String[] args) { List<String> stringList = Arrays.asList("1", "2", "3", "4"); // 定义String转Integer的Function Function<String, Integer> toInt = Integer::parseInt; // 堆代码 duidaima.com // 结合Stream使用Function:转换后过滤出偶数,再转为String List<String> result = stringList.stream() .map(toInt) // 应用转换 .filter(num -> num % 2 == 0) // 过滤偶数 .map(String::valueOf) // 转回String .collect(Collectors.toList()); System.out.println(result); // 输出:[2, 4] } }代码解析:首先定义String转Integer的Function,在Stream流中通过map方法应用该Function完成类型转换,后续链式调用filter和map完成过滤与二次转换。整个过程无需中间变量,逻辑清晰可见。
import java.util.function.Function; public class FunctionChaining { public static void main(String[] args) { // 第一步:String转Integer Function<String, Integer> strToInt = Integer::parseInt; // 第二步:Integer加10 Function<Integer, Integer> addTen = num -> num + 10; // 第三步:Integer转String Function<Integer, String> intToStr = String::valueOf; // 组合函数链:str -> int -> int+10 -> str Function<String, String> chain = strToInt.andThen(addTen).andThen(intToStr); String result = chain.apply("5"); // 应用函数链 System.out.println(result); // 输出:15 } }代码解析:通过andThen方法,我们将strToInt、addTen、intToStr三个Function按顺序组合为chain。调用apply时,输入的"5"会依次经过三步处理,最终得到"15"。andThen按"先当前后参数"的顺序执行,compose则相反(先参数后当前)。
import java.util.HashMap; import java.util.Map; import java.util.function.Function; public class DynamicFunctionSelection { // 定义操作类型 enum Operation { ADD, SUBTRACT, MULTIPLY } public static void main(String[] args) { // 用Map存储操作类型与对应Function的映射 Map<Operation, Function<Integer[], Integer>> operationMap = new HashMap<>(); operationMap.put(Operation.ADD, nums -> nums[0] + nums[1]); // 加法逻辑 operationMap.put(Operation.SUBTRACT, nums -> nums[0] - nums[1]); // 减法逻辑 operationMap.put(Operation.MULTIPLY, nums -> nums[0] * nums[1]); // 乘法逻辑 // 动态选择操作:根据Operation获取对应的Function并执行 Integer result = operationMap.get(Operation.ADD).apply(new Integer[]{3, 5}); System.out.println(result); // 输出:8 } }代码解析:通过Map建立Operation与Function的映射,每种操作对应一个计算逻辑。当需要执行运算时,只需根据Operation从Map中获取对应的Function并调用apply,无需if-else判断。
import java.util.function.Function; // 定义带异常处理的Function包装类 @FunctionalInterface interface ThrowingFunction<T, R, E extends Exception> { R apply(T t) throws E; } public class FunctionWithException { // 包装方法:处理异常并转换为普通Function public static <T, R, E extends Exception> Function<T, R> wrap(ThrowingFunction<T, R, E> throwingFunc) { return t -> { try { return throwingFunc.apply(t); // 执行带异常的逻辑 } catch (Exception e) { throw new RuntimeException(e); // 包装为运行时异常抛出 } }; } public static void main(String[] args) { // 使用包装类处理可能抛异常的转换(如Integer.parseInt可能抛NumberFormatException) Function<String, Integer> safeParser = wrap(Integer::parseInt); Integer result = safeParser.apply("123"); // 正常转换 System.out.println(result); // 输出:123 } }代码解析:定义ThrowingFunction接口允许抛出异常,通过wrap方法将其转换为普通Function,并在内部捕获异常并包装为RuntimeException。这样既保留了异常处理能力,又符合Function的接口规范。
import java.util.Optional; import java.util.function.Function; class User { private String name; private Address address; // 构造器、getter省略 public User(String name, Address address) { this.name = name; this.address = address; } public String getName() { return name; } public Address getAddress() { return address; } } class Address { private String city; // 构造器、getter省略 public Address(String city) { this.city = city; } public String getCity() { return city; } } public class OptionalWithFunction { public static void main(String[] args) { User user = new User("Alice", new Address("Beijing")); // 定义从User获取城市的Function链 Function<User, Address> getUserAddress = User::getAddress; Function<Address, String> getCity = Address::getCity; // 结合Optional:安全获取城市,避免空指针 String city = Optional.ofNullable(user) .map(getUserAddress) // 提取Address,若为null则终止 .map(getCity) // 提取city,若为null则终止 .orElse("Unknown"); // 最终为null时返回默认值 System.out.println(city); // 输出:Beijing } }代码解析:通过Optional的map方法,依次应用getUserAddress和getCity两个Function。若链中任何一步返回null,后续操作会终止,最终通过orElse返回默认值,全程无需显式null判断。
import java.util.ArrayList; import java.util.List; import java.util.function.Function; class User { private Long id; public User(Long id) { this.id = id; } public Long getId() { return id; } } class Order { private Long orderId; public Order(Long orderId) { this.orderId = orderId; } public Long getOrderId() { return orderId; } } public class GenericDataExtractor { // 通用提取方法:从列表中提取指定字段 public static <T, R> List<R> extract(List<T> list, Function<T, R> extractor) { List<R> result = new ArrayList<>(); for (T item : list) { result.add(extractor.apply(item)); // 应用提取规则 } return result; } public static void main(String[] args) { List<User> users = List.of(new User(1L), new User(2L)); List<Order> orders = List.of(new Order(100L), new Order(101L)); // 提取用户ID List<Long> userIds = extract(users, User::getId); // 提取订单ID List<Long> orderIds = extract(orders, Order::getOrderId); System.out.println(userIds); // 输出:[1, 2] System.out.println(orderIds); // 输出:[100, 101] } }代码解析:extract方法通过接收Function参数extractor,将数据提取逻辑与遍历逻辑分离。对于User和Order两种不同对象,只需传入对应的提取函数(User::getId和Order::getOrderId),即可复用同一提取方法。
import java.util.HashMap; import java.util.Map; import java.util.function.Function; public class CachedFunction { private final Map<Object, Object> cache = new HashMap<>(); // 缓存容器 // 缓存包装方法:先查缓存,无则计算并缓存结果 public <T, R> R computeIfAbsent(T key, Function<T, R> computeFunc) { if (cache.containsKey(key)) { // 检查缓存 return (R) cache.get(key); // 返回缓存值 } R result = computeFunc.apply(key); // 执行计算 cache.put(key, result); // 存入缓存 return result; } public static void main(String[] args) { CachedFunction cached = new CachedFunction(); // 定义耗时计算:模拟数据库查询 Function<Long, String> dbQuery = id -> { System.out.println("Executing query for id: " + id); return "User_" + id; }; // 第一次查询:计算并缓存 String user1 = cached.computeIfAbsent(1L, dbQuery); // 第二次查询:直接返回缓存 String user2 = cached.computeIfAbsent(1L, dbQuery); System.out.println(user1); // 输出:User_1 System.out.println(user2); // 输出:User_1 } }代码解析:computeIfAbsent方法接收缓存键key和计算函数computeFunc,先检查缓存中是否存在key,存在则返回缓存值,否则执行computeFunc计算并缓存结果。核心计算逻辑由Function封装,与缓存控制分离。
import java.util.HashMap; import java.util.Map; import java.util.function.Function; // 订单类 class Order { private double amount; private String userType; public Order(double amount, String userType) { this.amount = amount; this.userType = userType; } public double getAmount() { return amount; } public String getUserType() { return userType; } } public class StrategyWithFunction { public static void main(String[] args) { // 定义不同用户类型的折扣策略(Function<订单, 折后金额>) Map<String, Function<Order, Double>> discountStrategies = new HashMap<>(); discountStrategies.put("NEW", order -> order.getAmount() * 0.8); // 新用户8折 discountStrategies.put("MEMBER", order -> order.getAmount() * 0.9); // 会员9折 discountStrategies.put("DEFAULT", order -> order.getAmount()); // 默认无折扣 // 计算订单金额 Order order = new Order(100.0, "NEW"); double finalAmount = discountStrategies.getOrDefault( order.getUserType(), discountStrategies.get("DEFAULT") ).apply(order); System.out.println(finalAmount); // 输出:80.0 } }代码解析:用Map存储用户类型与折扣策略(Function)的映射,每个策略直接通过Lambda表达式定义,无需单独创建策略类。计算订单金额时,根据用户类型获取对应的Function并执行,完成折扣计算。
import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; // 订单DTO class OrderDTO { private String orderNo; private String userId; private double amount; // 构造器、getter省略 public OrderDTO(String orderNo, String userId, double amount) { this.orderNo = orderNo; this.userId = userId; this.amount = amount; } public String getOrderNo() { return orderNo; } public String getUserId() { return userId; } public double getAmount() { return amount; } } // 订单实体 class OrderEntity { private Long id; private String orderNo; private Long userId; private double finalAmount; // 构造器、getter、setter省略 public OrderEntity(Long id, String orderNo, Long userId, double finalAmount) { this.id = id; this.orderNo = orderNo; this.userId = userId; this.finalAmount = finalAmount; } @Override public String toString() { return "OrderEntity{id=" + id + ", orderNo='" + orderNo + "'}"; } } public class ProjectApplication { public static void main(String[] args) { // 1. DTO转实体的基础转换 Function<OrderDTO, OrderEntity> baseConverter = dto -> new OrderEntity(null, dto.getOrderNo(), null, dto.getAmount()); // 2. 补充用户ID(String转Long) Function<OrderEntity, OrderEntity> addUserId = entity -> { String userIdStr = "123"; // 实际从上下文获取 entity = new OrderEntity(entity.getId(), entity.getOrderNo(), Long.parseLong(userIdStr), entity.getFinalAmount()); return entity; }; // 3. 应用折扣策略 Function<OrderEntity, OrderEntity> applyDiscount = entity -> { double discounted = entity.getFinalAmount() * 0.9; // 会员折扣 return new OrderEntity(entity.getId(), entity.getOrderNo(), entity.getUserId(), discounted); }; // 4. 组合转换链:DTO→基础实体→补充用户ID→应用折扣 Function<OrderDTO, OrderEntity> fullConverter = baseConverter .andThen(addUserId) .andThen(applyDiscount); // 5. 批量处理订单 List<OrderDTO> dtos = List.of( new OrderDTO("ORD001", "123", 100.0), new OrderDTO("ORD002", "123", 200.0) ); // 堆代码 duidaima.com List<OrderEntity> entities = dtos.stream() .map(fullConverter) .collect(Collectors.toList()); System.out.println(entities); // 输出:[OrderEntity{id=null, orderNo='ORD001'}, OrderEntity{id=null, orderNo='ORD002'}] } }代码解析:在订单处理流程中,首先定义DTO到实体的基础转换Function,再通过andThen组合补充用户ID和应用折扣的Function,形成完整转换链。结合Stream的map方法,实现批量DTO到实体的转换,逻辑清晰且易于扩展。