Guava TreeBasedTable - 按列排序

Guava TreeBasedTable - Sort By Column

我正在尝试使用 Guava Table and TreeBaedTable 实现,并且正在尝试按列名对 table 进行排序。这是我目前所拥有的:

import com.google.common.collect.Ordering;
import com.google.common.collect.Table;
import com.google.common.collect.TreeBasedTable;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;


public class CustomTable {
    enum SortDirection {
        ASC, DESC,
    }

    enum Column {
        COL_1, COL_2, COL_3;
        public static final Column[] columns = Column.values();
    }

    private final TreeBasedTable<Integer, Column, Integer> table;

    public CustomTable() {
        this.table = TreeBasedTable.create();
    }

    public Integer cell(int ID, Column column) {
        return table.get(ID, column);
    }

    public void addRow(List<Integer> values) {
        Integer rowNum = nextID();
        for (int i = 0; i < values.size(); i++) {
            table.put(rowNum, Column.columns[i], values.get(i));
        }
    }

    public Table<Integer, Column, Integer> sortBy(Column column, SortDirection sortDirection) {
        Comparator<Integer> rowComparator = Comparator.comparing(id -> cell(id, column));
        rowComparator = (sortDirection.equals(SortDirection.ASC)) ? rowComparator : rowComparator.reversed();
        Table<Integer, Column, Integer> table = TreeBasedTable.create(rowComparator, Ordering.natural());
        table.putAll(table);
        return table;
    }

    public String toString() {
        return table.toString();
    }

    public int maxID() {
        return table.rowKeySet().size();
    }

    public int nextID() {
        return maxID() + 1;
    }
}

以及用法示例:

CustomTable table = new CustomTable();
table.addRow(Arrays.asList(1, 2, 3));
table.addRow(Arrays.asList(6, 7, 8));
table.addRow(Arrays.asList(4, 5, 6));
System.out.println(table.sortBy(Column.COL_2, SortDirection.DESC));

现在,当单元格具有不同的值时,这会按预期工作。但是,如果两个单元格具有相同的值,则省略后者。

我已尝试使用以下比较器解决此问题:

Comparator<Integer> rowComparator = (id1, id2) -> {
    Integer cell1 = cell(id1, column);
    Integer cell2 = cell(id2, column);
    if (cell1 != cell2)
        return cell1.compareTo(cell2);
    return -1; // So, row id1 appears above the row id2.
};

但这会产生一些不需要的 table 突变。有什么我想念的吗?

使用 print 语句,我注意到 ID 正在根据自身进行检查,即 id1 == id2 当两个不同的单元格具有相同的值时。解决方案是捕捉这种情况和 return 0(当两个 Integer 对象具有相同的值时)。

那么使用的比较器是:

Comparator<Integer> valueComparator = (id1, id2) -> {
    if (id1.equals(id2))
        return 0;
    Integer cell1 = cell(id1, column);
    Integer cell2 = cell(id2, column);
    if (cell1.equals(cell2))
        return 1;
    return cell1.compareTo(cell2);
};

它按预期工作; returning 1 当两个单元格共享相同的值时保持原始插入顺序。

附带说明一下,如果有多个单元格具有相同的值(例如,超过 5 个重复的单元格),在打印 table 时,一些数据可能会丢失。然而,查询table显示所有的数据都还在,只是出于某种我不知道的原因,toString方法没有输出一些行。