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
方法没有输出一些行。
我正在尝试使用 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
方法没有输出一些行。