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

如何提升包含9列及以上数据的FilteredList的过滤性能

性能优化方案

核心瓶颈分析

当前性能损耗完全来自自定义的过滤谓词逻辑,和FilteredList本身无关:

  1. 每一行每一列过滤时都重复调用getCellObservableValue、取值、转字符串,重复计算开销大
  2. 用List存储选中的过滤值,匹配时需要遍历,时间复杂度为O(n),选中值越多性能越差
  3. 不管列是否启用了过滤规则,所有9列的判断逻辑都会执行,存在无效计算

具体优化措施

  • 预缓存列取值逻辑:初始化ColumnFilter时就提前绑定好当前列的取值函数,避免每次过滤时重复通过TableColumn反射读取属性,同时可按需缓存行的列值字符串,避免重复调用toString
  • 替换匹配集合类型:将选中的过滤值从List改为HashSet,匹配操作时间复杂度从O(n)降到O(1)
  • 跳过无效过滤判断:给ColumnFilter新增激活状态判断,当列没有选中过滤项、或者选中全部选项时,直接跳过该列的过滤逻辑,不需要执行匹配
  • 提前组装有效谓词:每次过滤规则变更时,先筛选出当前处于激活状态的过滤器列表,避免对每一行数据都遍历全量过滤器

优化后代码示例

public class ColumnFilter<T> {
    private final Function<T, String> valueExtractor;
    private Set<String> selectedValues = Collections.emptySet();
    private boolean isActive = false;

    public ColumnFilter(TableFilter filter, TableColumn<T, ?> column) {
        // 提前初始化取值逻辑,仅执行一次
        this.valueExtractor = item -> {
            if (item == null) return "";
            Object val = column.getCellObservableValue(item).getValue();
            return val == null ? "" : val.toString();
        };
    }

    // 过滤选项变更时同步更新状态,仅在选项变化时执行
    public void updateFilterConfig(List<String> selected, boolean isAllSelected) {
        this.selectedValues = new HashSet<>(selected);
        this.isActive = !selected.isEmpty() && !isAllSelected;
    }

    public boolean filter(T item) {
        if (!isActive) return true;
        return selectedValues.contains(valueExtractor.apply(item));
    }
}

public class TableFilter<T> {
    // ... 原有构造逻辑保留
    public void filter() {
        // 提前筛选激活的过滤器,仅执行一次
        List<ColumnFilter<T>> activeFilters = columnFilters.stream()
                .filter(ColumnFilter::isActive)
                .toList();
        if (activeFilters.isEmpty()) {
            filterList.setPredicate(null);
            return;
        }
        filterList.setPredicate(item -> {
            for (ColumnFilter<T> f : activeFilters) {
                if (!f.filter(item)) return false;
            }
            return true;
        });
    }
}

是否需要替换FilteredList

不需要,FilteredList本身是JavaFX提供的轻量过滤实现,本身开销极低,当前的性能问题完全是自定义谓词的逻辑问题,优化后5000行数据9列全过滤的耗时可以控制在几十毫秒量级,完全满足使用需求。

额外可选优化:如果存在连续勾选多个过滤选项的场景,可以给过滤操作加100ms以内的防抖,避免频繁触发过滤重计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 08:45:04