Первый элемент в дереве становится нулевым? Guava TreebasedTable - PullRequest
3 голосов
/ 22 августа 2011

Так что у меня возникла проблема с таблицей Guava TreeBasedTable (если вы незнакомы, это дерево, которое обращается к своим элементам на основе пары ключей), которое на прошлой неделе было медвежьим для выяснения. Я сделаю все возможное, чтобы объяснить, удалив лишний код:

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);
    }
}

По сути, я перебираю некоторые данные, которые у меня есть, делаю некоторые вычисления и помещаю результаты в таблицу. Что странно, когда я пытаюсь получить доступ к элементам. Если я просто переберу их следующим образом:

for(Result r : results.values()){
    System.out.println(r);
}

все работает нормально. Однако, если я попытаюсь получить к ним доступ следующим образом:

for(RowValue row : results.rowKeySet()){
    for(Data d : results.columnKeySet()){
        System.out.println(results.get(row, d));
    }
}

Первый элемент как-то нулевой. Однако, если дерево имеет размер 1, оно работает нормально. Может быть, здесь что-то происходит с Деревьями, чего я не понимаю? Извините за длинный вопрос, надеюсь, это было понятно.

:: EDIT :: Первое значение, переданное в дерево, всегда ненулевое. Однако, когда дерево достигает размера 3, оно превращается из ненулевого в нулевое. Извините, если не совсем понятно, в чем была моя проблема. В соответствии с запросом приведен фактический код с актуальными ключами:

public void createResults (параметры параметров, данные MeasuredData, методы ArrayList) {

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);
           }
     }
}

Итак, я провел ряд вычислений для ряда соединений, каждое из которых может дать несколько результатов. Можно ли как-то это прояснить?

1 Ответ

5 голосов
/ 23 августа 2011

rowKeySet() - это набор всех строк, а columnKeySet() - это набор всех столбцов таблицы.Тем не менее, вполне может быть и так, что существует значение для каждой комбинации ключа строки и ключа столбца.Например, может быть, вы рассчитали результат только с определенным RowValue для одного из Data объектов.Комбинация этого объекта RowValue (ключ строки) и любого другого объекта Data (ключ столбца) в этом случае не будет отображаться в Result.Вполне вероятно, что вы видите что-то подобное.

Чтобы перебирать только действительные сопоставления, вам нужно сделать что-то вроде этого:

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));
  }
}

Редактировать:

Насколько я понимаю, что происходит, в таблице не указывается значение null.Скорее происходит нечто подобное:

Table<Integer, Integer, String> table = TreeBasedTable.create();
table.put(1, 1, "Foo");
table.put(2, 2, "Bar");

Обратите внимание, что во всей таблице есть строки 1 и 2 и столбцы 1 и 2.Однако в столбце 1 строки 1 имеется только значение, а в столбце 2 строки 2.Поэтому, когда мы перебираем все возможные комбинации строки и столбца, как вы делаете в вашем примере, мы выводим значения в строке 1, столбце 2 и в строке 2, столбце 1, оба из которыхвернуть null, поскольку в этих ячейках не было помещено значение ... вызов table.contains(1, 2) возвращает false.

...