You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何复用循环逻辑遍历Dog、Cat两类列表实现独立打印

重复循环逻辑优化方案

这类重复代码的核心问题是把遍历执行、筛选规则、输出逻辑三个独立逻辑耦合在了每个分支里,只要把公共的遍历逻辑抽离,把可变的筛选、输出逻辑作为参数传入,就能彻底消除重复的循环代码,后续扩展也更方便。

方案1:利用多态做抽象(推荐,适合可修改实体类的场景)

先给Dog、Cat抽公共的行为接口,统一两类实体的公共方法:

public interface Animal {
    // 统一获取领养状态的方法
    String getStatus();
    // 每个动物自己实现自己的信息打印逻辑
    void printInfo();
}

让Dog、Cat类都实现这个接口,把各自的打印逻辑写在自己的printInfo()方法里,不用把输出规则堆在公共打印方法中。

之后抽离唯一的一份通用遍历方法,把筛选规则作为可传参数:

// 通用遍历打印工具方法
private static void printAnimalList(List<? extends Animal> animalList, Predicate<Animal> filter) {
    for (Animal animal : animalList) {
        // 无过滤条件 或 满足过滤规则时执行打印
        if (filter == null || filter.test(animal)) {
            animal.printInfo();
        }
    }
}

最后改造原来的分支逻辑,去掉所有重复的for循环:

public static void printAnimals(String listType) {
    switch (listType) {
        case "dog":
            printAnimalList(dogList, null);
            break;
        case "cat":
            printAnimalList(catList, null);
            break;
        case "available":
            Predicate<Animal> unreservedFilter = animal -> "unreserved".equals(animal.getStatus());
            printAnimalList(dogList, unreservedFilter);
            printAnimalList(catList, unreservedFilter);
            break;
        default:
            throw new IllegalArgumentException("不支持的列表类型:" + listType);
    }
}

这个方案的优势:

  • 遍历逻辑全局只保留一份,后续修改遍历规则(比如加序号打印、统一异常捕获)只需要改一个地方
  • 每个实体类自己管自己的打印逻辑,符合单一职责,修改单个动物的输出格式不需要动公共遍历代码
  • 筛选逻辑可插拔,后续新增其他筛选规则(比如打印3岁以下的宠物、打印特定品种的宠物)只需要传入新的Predicate即可,不需要改动核心遍历逻辑
  • 后续新增动物类型(比如兔子、仓鼠)时,只要实现Animal接口,在分支里加一行调用即可,不需要重复写任何遍历逻辑

方案2:泛型通用方法(适合无法修改原有实体类的场景)

如果Dog、Cat是第三方依赖的类,没法直接修改源码让它们实现接口,可以用泛型+函数式参数的方式抽离遍历逻辑,完全不侵入原有代码:

/**
 * 通用列表遍历打印方法
 * @param list 待遍历的任意类型列表
 * @param filter 元素筛选规则,传null表示不筛选
 * @param printer 元素的打印逻辑
 */
private static <T> void printGenericList(List<T> list, Predicate<T> filter, Consumer<T> printer) {
    for (T item : list) {
        if (filter == null || filter.test(item)) {
            printer.accept(item);
        }
    }
}

调用时按需传入筛选和打印规则即可,比如打印可领养动物的分支可以写成:

case "available":
    // 打印未预定的狗
    printGenericList(dogList,
        dog -> "unreserved".equals(dog.getStatus()),
        dog -> System.out.println("unreserved dogs: " + dog)
    );
    // 打印未预定的猫
    printGenericList(catList,
        cat -> "unreserved".equals(cat.getStatus()),
        cat -> System.out.println("unreserved cats: " + cat)
    );
    break;

这种写法灵活度极高,不管后续要加什么类型的列表、什么筛选规则、什么输出格式,都不用再重复写for循环结构。


额外注意

原代码中字符串比较的写法存在空指针风险,所有listType.equals("xxx")都建议改成"xxx".equals(listType),或者用Objects.equals(listType, "xxx"),避免入参为null时直接抛出异常。

内容的提问来源于stack exchange,提问作者user18942073

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 19:24:19