【问题标题】:Insert all records in an Iterable<Object> to a List in java将 Iterable<Object> 中的所有记录插入到 java 中的 List
【发布时间】:2012-12-20 07:47:06
【问题描述】:

我有一个 Iterable&lt;MyRecord&gt; records 。我遍历下面的记录并将其添加到 LinkedList 中,如下所示。

对于(MyRecord 记录:记录){ sortedList.addLast(record); }

我的 iterable 有 3 条记录,它们都有不同的值。但最后虽然sortedList 包含3 条记录,但所有3 条都是一样的!!!。怎么会?

当我打印出内存位置时,所有3个都是一样的。我做错了什么?

【问题讨论】:

  • 这可能有很多原因...您如何创建可迭代的记录?也许它们在可迭代的记录中已经相同了?而且......如果你有一个Iterable&lt;MyRecord&gt; records 不应该for循环也将记录读取为“MyRecord”而不是“AccountRecord”
  • 不能用sortedList.addAll(records)
  • @Chris 实际上在 hadoop 的 reduce 部分。在这里检查。 hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/mapreduce/…, java.lang.Iterable, org.apache.hadoop.mapreduce.Reducer.Context)
  • 你自己实现了Iterable接口吗?如果是这样,您的 iterator() 实现可能是错误的。记录的类型是什么?
  • @Chris 实际上是 MyRecord。对不起。

标签: java collections hadoop iterator


【解决方案1】:

实际上,您的评论揭示了为什么会出错的缺失链接。您在 Hadoop 映射器或减速器中使用它。 Hadoop 的诀窍在于它重用了你进入的对象,因此它在垃圾收集器上很容易。因此,您需要做的是复制源可迭代对象(MyRecords)中的每个对象,然后将它们添加到您的 LinkedList。

【讨论】:

  • 记住你必须进行深拷贝——如果你还没有拷贝构造函数,你可能想考虑使用 ReflectionUtils.copy(conf, source, destination) 它会为你处理一切- API Docs
【解决方案2】:

如果 sortedList 包含相同的记录,即原始记录中的最后一个元素,则迭代器可能会重复使用 tmp 引用。您需要检查“记录”的执行情况。

【讨论】:

    【解决方案3】:

    您的问题很清楚,代码也很清楚(也在阅读 cmets 之后);这可能无济于事,但也许你可以在添加之前做一个包含检查,如:if (sortedList.contains(record)) sortedList.add...

    我承认这可能没有真正的帮助(我也不知道是否包含检查引擎盖下的元素内存位置,因为我猜它可能只使用 equals 检查列表中的元素存在)。

    【讨论】:

      【解决方案4】:

      当您将项目添加到列表中时,请检查:

      if(sortedList.contains(record))
      {
        System.out.println("Record is already available "+record);
      }
      else
      {
       sortedList.addLast(record);
      }
      

      您将了解问题是由于相同的记录还是由于其他原因。

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 2021-01-21
        • 1970-01-01
        • 2020-07-19
        • 2021-07-23
        • 1970-01-01
        • 1970-01-01
        • 2018-07-17
        • 2016-08-05
        相关资源
        最近更新 更多