【问题标题】:How can I reuse collections that would use the same backing iterator?如何重用使用相同支持迭代器的集合?
【发布时间】:2014-10-03 19:39:37
【问题描述】:

我对 Java 还很陌生,所以我的知识非常有限。我正在做一个个人项目,我正在尝试在 Guava 中使用的一些技术来创建集合的视图/转换。我创建了一个名为 View 的类,将输入的集合作为支持迭代和转换,然后将其呈现为只读迭代。 (不是一个集合,虽然我认为这对这个问题没有太大影响)。这是一个使用它的简单示例...

public class Node {
  public enum Change implements Function<Node, Coordinate> {
    TO_COORDINATE;
    @Override public Coordinate apply(Node node) {
      return new Coordinate(node);
    }
  }

  private HashSet<Node> neighborNodes = new HashSet<Node>();
  //various other members

  public View<Coordinate> viewNeighborCoordinates() {
    return new View<Coordinate>(neighborNodes, Change.TO_COORDINATE);
  }
}

现在如果某个方法想使用这个节点的viewNeighborCoordinates(),然后其他方法也想用这个节点的viewNeighborCoordinates(),总是返回新对象似乎很浪费,对吧?我的意思是任何数量的东西都应该能够共享对具有相同转换的相同支持迭代的视图的引用,因为他们所做的只是通读它。是否有一种既定的方法来管理可以像字符串一样“实习”的对象共享池?是否只需要创建某种 ViewFactory 来存储正在使用的视图的运行列表,并且每次有人想要一个视图时,它都会检查它是否已经拥有该视图并将其分发出去? (这样更有效率吗)?

【问题讨论】:

  • 这是可能的,但不太可能有帮助。将视图包裹在对象周围很便宜(可能比找到现有的等效视图便宜),并且除非您期望大量相同的视图同时处于活动状态,否则它对内存使用没有帮助。
  • 另外,你混淆了迭代器和可迭代对象。
  • 抱歉,改成 backing iterable。

标签: java collections iterator guava


【解决方案1】:

如前所述,实习是可能的(查看Interners),但很可能是个坏主意。

另一种可能性是延迟初始化存储View 的字段。由于我也很懒,所以我只为您指出一个 Lombok 实现。如果你想试试这个,请小心DCL。如果您的类是不可变的,您可能根本不需要同步,例如String.hashCode.

一个非常简单的可能性是字段的急切初始化。假设您经常需要视图,这是最好的方法。

但在不了解更多信息的情况下,您当前的实现是最好的。当心root of all evil

不要在没有分析或基准测试的情况下进行优化(如果您进行基准测试,那么就做正确的事,即使用caliperjmh。Java 中的自制基准测试不起作用)。

【讨论】:

    猜你喜欢
    • 2014-01-11
    • 2010-12-19
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多