【问题标题】:First element in tree becoming null? Guava TreebasedTable树中的第一个元素变为空? Guava 基于树的表
【发布时间】:2011-08-22 19:53:43
【问题描述】:

所以我遇到了 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,则它可以正常工作。会不会是这里发生了一些我不理解的关于 Trees 的事情?对不起,问题很长,我希望它很清楚。

::EDIT:: 传入树的第一个值总是非空的。然而,当树达到大小 3 时,它会从非空变为空。抱歉,如果不清楚我的问题是什么。 根据要求,这是带有实际键的实际代码:

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

因此,我对多种化合物进行了多次计算,每一种都可以产生多个结果。有什么办法可以澄清一下吗?

【问题讨论】:

  • 这并不是我所说的一个小而独立的例子。我的意思更像是使用 Strings 或 Integer 键的东西,我实际上可以运行这些键来查看您所描述的行为。也就是说,Result.getMethod() 是否会返回相同的 Method 或通过调用 method.calculate 生成的每个 Result 不同的 Method?如果相同,您需要为每个 Compound/Method 组合存储某种 Collection&lt;Result&gt; 值,否则您将覆盖结果。
  • 是的,很抱歉。我现在怀疑 MethodDescriptor 的 compareTo 方法中发生了一些事情(有点像你刚才建议的),所以我正在解决这个问题。如果解决了,我会告诉你的。非常感谢!
  • 是的,比较器搞砸了!非常感谢您的帮助!

标签: java data-structures tree guava


【解决方案1】:

rowKeySet() 是所有行的集合,columnKeySet() 是表的所有列的集合。但是,行键和列键的每个组合都可能没有一个值。例如,您可能只为Data 对象之一计算了具有特定RowValue 的结果。在这种情况下,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。

【讨论】:

  • 好的,所以你是正确的,因为它不再打印出空值(upvote)。但是,我的问题不仅仅是价值首先是空的。发生的情况是,第一个值传入(非null),第二个值传入,然后当第三个传入时,第一个值变为null。
  • @Steve:所以你是说你传入了 2 个非空值,然后当你传入第 3 个值时,你只会看到 null 以及表中的第 2 个和第 3 个值?如果您在迭代 values() 或以我描述的方式迭代时看到所有期望的值,我仍然认为我所描述的就是正在发生的事情。一个包含实际键和值的简短、独立的示例会有所帮助。
猜你喜欢
  • 2022-11-03
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-01
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多