So I am having a problem with a Guava TreeBasedTable (if you're unfamiliar, it's a tree that accesses its elements based on a pair of keys) which over the past week has been a bear to figure out. I'll do my best to explain, removing superfluous code:
TreeBasedTable<RowValue, Data, Result> results = TreeBasedTable.create();
for (Data d : data.getData()) {
for (Operation o: data.getOperations()) {
Result r = o.calculate(...);
results.put(r.rowValue, d, r);
}
}
Basically, I iterate over some data that I have, do some calculations, and stick the results in the table. What's strange though, is when I try to开发者_C百科 access the elements. If I simply iterate over them as follows:
for(Result r : results.values()){
System.out.println(r);
}
everything works normally. However, if I instead try to access them as follows:
for(RowValue row : results.rowKeySet()){
for(Data d : results.columnKeySet()){
System.out.println(results.get(row, d));
}
}
The first element is null somehow. If however the tree is of size 1, it works fine. Could it be there is something about Trees going on here that I am not understanding? Sorry for the long question, I hope it was clear.
::EDIT:: The first value passed into the tree is always non-null. When the tree reaches size 3 however, it turns from non-null, to null. Sorry if it wasn't exactly clear what my problem was. As requested, here is the actual code with the actual keys:
public void createResults(Options options, MeasuredData data, ArrayList methods) {
private TreeBasedTable<MethodDescriptor, Compound, Result> results = TreeBasedTable.create();
for (Compound c : data.getCompounds()) {
for (Method method : methods) {
ArrayList<Result> calcResults = method.calculate(c, options);
for (Result r : calcResults) {
results.put(r.getMethod(), c, r);
}
}
}
So I run a number of computations on a number of compounds, each of which can produce multiple results. Is there any way I can clarify this?
The rowKeySet()
is the set of all rows and the columnKeySet()
is the set of all columns for the table. However, it may well not be the case that there is a value for every combination of row key and column key. For example, maybe you only calculated a result with a certain RowValue
for one of the Data
objects. The combination of that RowValue
object (row key) and any other Data
object (column key) would not map to a Result
in that case. It seems likely that you're seeing something like this.
To only iterate over the valid mappings, you'd want to do something like this:
for (RowValue row : results.rowKeySet()) {
// Only iterate over the columns that actually have values for this row
for (Data d : results.row(row).keySet()) {
System.out.println(results.get(row, d));
}
}
Edit:
From my understanding of what's happening, no null
is being set as a value in the table. Rather, something like this is happening:
Table<Integer, Integer, String> table = TreeBasedTable.create();
table.put(1, 1, "Foo");
table.put(2, 2, "Bar");
Note that in the entire table, there are rows 1
and 2
and columns 1
and 2
. However, there is only a value at column 1
of row 1
and at column 2
of row 2
. So when we iterate through every possible combination of row and column, as you do in your example, we print out the values at row 1
, column 2
and at row 2
, column 1
, both of which return null
since no value was placed at those cells... calling table.contains(1, 2)
returns false
.
精彩评论