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

如何在JTable中对单列LocalDateTime格式的数据正确排序?

Great job getting this working with a custom Comparator on the TableRowSorter—that's a solid approach for cases where your table model is holding string representations of dates. Let's break down some improvements you can make to make this code more robust, efficient, and clean:

1. Reuse the DateTimeFormatter

Right now, you're creating a new DateTimeFormatter instance every time the compare method runs. Since your date pattern is fixed, you can initialize it once as a static final variable outside the comparator to avoid unnecessary object creation:

private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.uuuu HH:mm:ss");

// Then in your comparator setup:
sorter.setComparator(columnIndexToSort, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        LocalDateTime ldt1 = LocalDateTime.parse(o1, DATE_FORMATTER);
        LocalDateTime ldt2 = LocalDateTime.parse(o2, DATE_FORMATTER);
        return ldt1.compareTo(ldt2);
    }
});

2. Handle Invalid Date Strings

If any cell in your date column has a string that doesn't match the dd.MM.uuuu HH:mm:ss pattern, LocalDateTime.parse() will throw a DateTimeParseException, which will crash the sorting operation. Add error handling to define how invalid dates should be ordered—for example, pushing them to the end:

sorter.setComparator(columnIndexToSort, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        try {
            LocalDateTime ldt1 = LocalDateTime.parse(o1, DATE_FORMATTER);
            LocalDateTime ldt2 = LocalDateTime.parse(o2, DATE_FORMATTER);
            return ldt1.compareTo(ldt2);
        } catch (DateTimeParseException e) {
            // Define behavior for invalid dates
            boolean o1Invalid = o1 == null || !o1.matches("\\d{2}\\.\\d{2}\\.\\d{4} \\d{2}:\\d{2}:\\d{2}");
            boolean o2Invalid = o2 == null || !o2.matches("\\d{2}\\.\\d{2}\\.\\d{4} \\d{2}:\\d{2}:\\d{2}");
            if (o1Invalid && o2Invalid) return 0; // Treat both as equal
            return o1Invalid ? 1 : -1; // Invalid dates go last
        }
    }
});

3. Simplify with Lambdas

Since Java 8, you can replace the anonymous Comparator class with a lambda expression to make the code more concise without losing clarity:

sorter.setComparator(columnIndexToSort, (o1, o2) -> {
    try {
        LocalDateTime ldt1 = LocalDateTime.parse(o1, DATE_FORMATTER);
        LocalDateTime ldt2 = LocalDateTime.parse(o2, DATE_FORMATTER);
        return ldt1.compareTo(ldt2);
    } catch (DateTimeParseException e) {
        boolean o1Invalid = o1 == null || !o1.matches("\\d{2}\\.\\d{2}\\.\\d{4} \\d{2}:\\d{2}:\\d{2}");
        boolean o2Invalid = o2 == null || !o2.matches("\\d{2}\\.\\d{2}\\.\\d{4} \\d{2}:\\d{2}:\\d{2}");
        if (o1Invalid && o2Invalid) return 0;
        return o1Invalid ? 1 : -1;
    }
});

4. Align Table Model with Actual Data Type (Cleaner Long-Term Fix)

Your initial attempt to use getColumnClass() to return LocalDateTime.class didn't work because your table model was still returning String values from getValueAt(). If you can modify your TableModel to store and return LocalDateTime objects directly (instead of strings), you won't need a custom comparator at all—TableRowSorter will automatically use the natural ordering of LocalDateTime:

@Override
public Class<?> getColumnClass(final int columnIndex) {
    if (getColumnName(columnIndex).equals("Datecolumn")) {
        return LocalDateTime.class;
    }
    // Fallback logic for other columns
    try {
        return getValueAt(0, columnIndex).getClass();
    } catch (Exception e) {
        return String.class;
    }
}

// Update getValueAt() to return LocalDateTime for the date column
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    if (getColumnName(columnIndex).equals("Datecolumn")) {
        // Parse your stored string once into LocalDateTime
        String dateStr = yourDataStore.get(rowIndex).getDateString();
        return LocalDateTime.parse(dateStr, DATE_FORMATTER);
    }
    // Return other values as before
    return yourDataStore.get(rowIndex).getColumnValue(columnIndex);
}

// Then sorting becomes as simple as:
table.setAutoCreateRowSorter(true);

This approach keeps your data model more type-safe and avoids repeated string parsing during sorting.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:27:59