MST
星途 面试题库

面试题:Java Stream逻辑解耦在复杂业务场景下的应用

假设你正在开发一个电商系统,需要从大量的订单数据(包含订单信息、商品信息、用户信息等多个关联对象)中筛选出特定用户在特定时间段内购买的特定类型商品,并计算这些商品的总金额。请分别使用Java Stream和传统foreach来实现该功能,并分析Java Stream在这种复杂业务场景下逻辑解耦的优势体现在哪里。
49.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

使用Java Stream实现

import java.util.ArrayList;
import java.util.List;

class Order {
    private User user;
    private Product product;
    private long orderTime;

    public Order(User user, Product product, long orderTime) {
        this.user = user;
        this.product = product;
        this.orderTime = orderTime;
    }

    public User getUser() {
        return user;
    }

    public Product getProduct() {
        return product;
    }

    public long getOrderTime() {
        return orderTime;
    }
}

class User {
    private String id;

    public User(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

class Product {
    private String type;
    private double price;

    public Product(String type, double price) {
        this.type = type;
        this.price = price;
    }

    public String getType() {
        return type;
    }

    public double getPrice() {
        return price;
    }
}

public class EcommerceSystem {
    public static void main(String[] args) {
        List<Order> orders = new ArrayList<>();
        // 初始化订单数据
        orders.add(new Order(new User("1"), new Product("electronics", 100.0), 1600000000000L));
        orders.add(new Order(new User("2"), new Product("clothes", 50.0), 1600000001000L));
        orders.add(new Order(new User("1"), new Product("electronics", 200.0), 1600000002000L));

        String targetUserId = "1";
        long startTime = 1600000000000L;
        long endTime = 1600000002000L;
        String targetProductType = "electronics";

        double totalAmount = orders.stream()
               .filter(order -> targetUserId.equals(order.getUser().getId())
                        && order.getOrderTime() >= startTime && order.getOrderTime() <= endTime
                        && targetProductType.equals(order.getProduct().getType()))
               .mapToDouble(order -> order.getProduct().getPrice())
               .sum();

        System.out.println("Total amount: " + totalAmount);
    }
}

使用传统foreach实现

import java.util.ArrayList;
import java.util.List;

class Order {
    private User user;
    private Product product;
    private long orderTime;

    public Order(User user, Product product, long orderTime) {
        this.user = user;
        this.product = product;
        this.orderTime = orderTime;
    }

    public User getUser() {
        return user;
    }

    public Product getProduct() {
        return product;
    }

    public long getOrderTime() {
        return orderTime;
    }
}

class User {
    private String id;

    public User(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

class Product {
    private String type;
    private double price;

    public Product(String type, double price) {
        this.type = type;
        this.price = price;
    }

    public String getType() {
        return type;
    }

    public double getPrice() {
        return price;
    }
}

public class EcommerceSystem {
    public static void main(String[] args) {
        List<Order> orders = new ArrayList<>();
        // 初始化订单数据
        orders.add(new Order(new User("1"), new Product("electronics", 100.0), 1600000000000L));
        orders.add(new Order(new User("2"), new Product("clothes", 50.0), 1600000001000L));
        orders.add(new Order(new User("1"), new Product("electronics", 200.0), 1600000002000L));

        String targetUserId = "1";
        long startTime = 1600000000000L;
        long endTime = 1600000002000L;
        String targetProductType = "electronics";

        double totalAmount = 0;
        for (Order order : orders) {
            if (targetUserId.equals(order.getUser().getId())
                    && order.getOrderTime() >= startTime && order.getOrderTime() <= endTime
                    && targetProductType.equals(order.getProduct().getType())) {
                totalAmount += order.getProduct().getPrice();
            }
        }

        System.out.println("Total amount: " + totalAmount);
    }
}

Java Stream在复杂业务场景下逻辑解耦的优势

  1. 声明式编程风格:Java Stream使用声明式编程,只需要描述要做什么,而不是怎么做。例如在Stream代码中,通过filter描述筛选条件,mapToDouble描述提取价格操作,sum描述求和操作。而传统foreach是命令式编程,需要详细描述循环内的每一步操作,逻辑耦合度高。
  2. 代码可读性增强:Stream的链式调用使得代码更清晰,每个操作步骤一目了然,如筛选用户、时间范围、商品类型以及计算总金额,这些步骤在Stream代码中清晰呈现。而foreach循环中所有逻辑都混杂在循环体内,可读性较差。
  3. 易于维护和扩展:如果需求发生变化,例如需要添加新的筛选条件,在Stream中只需在filter操作中添加新条件即可,对其他部分代码影响小。而在foreach循环中,可能需要在复杂的循环体逻辑中进行修改,容易引入错误。
  4. 并行处理:Java Stream可以方便地进行并行处理,通过parallelStream,在多核环境下可以显著提高处理效率,并且不需要开发者手动管理线程。而传统foreach要实现并行处理则需要手动编写多线程代码,增加了代码复杂度和耦合度。