Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Iterable创建列表时要使用哪个实现_Java_Performance_List_Memory Management - Fatal编程技术网

Java 从Iterable创建列表时要使用哪个实现

Java 从Iterable创建列表时要使用哪个实现,java,performance,list,memory-management,Java,Performance,List,Memory Management,我发现自己经常做以下事情: Iterator<A> itr = iterableOfA.getIterator(); List<B> list = new ArrayList<>(); // how about LinkedList? while (itr.hasNext()) { B obj = iter.next().getB(); list.add(obj); } someMethod(list); // this method take

我发现自己经常做以下事情:

Iterator<A> itr = iterableOfA.getIterator();
List<B> list = new ArrayList<>(); // how about LinkedList?
while (itr.hasNext()) {
    B obj = iter.next().getB();
    list.add(obj);
}
someMethod(list); // this method takes an Iterable
这意味着对
iterableOfA
进行两次迭代。当iterable的大小未知且变化很大时,哪种选择最好:

  • 只需使用
    ArrayList
  • 只需使用
    LinkedList
  • iterableOfA
    中的元素进行计数,并分配一个
    ArrayList
  • 编辑1 为了澄清一些细节:

  • 我主要针对性能进行优化,其次针对内存使用进行优化
  • 列表
    是一种短期分配,因为在请求结束时,任何代码都不应包含对它的引用
  • 编辑2 在我的具体案例中,我意识到
    someMethod(list)
    无法处理超过200个元素的iterable,因此我决定使用
    新的ArrayList(200)
    ,这对我来说已经足够好了

    然而,在一般情况下,我更愿意实现公认答案中概述的解决方案(使用自定义iterable包装,避免分配列表的需要)

    所有其他答案都提供了非常有价值的见解,让我们了解了
    ArrayList
    LinkedList
    相比有多合适,因此我谨代表so社区感谢大家

    当iterable的大小未知且变化很大时,哪种选择最好

    这取决于你在优化什么

    • 如果您正在优化性能,那么使用
      ArrayList
      可能会更快。即使
      ArrayList
      需要调整备份阵列的大小,它也会使用指数增长模式进行调整。然而,这取决于迭代的开销

    • <> L> > P>如果您对长期内存使用进行优化,请考虑使用<代码> ARAYLISTAB/COD> >其次是代码> Trimtosiz()/<代码> < /P>
    • 如果您正在优化峰值内存使用,那么“计数优先”方法可能是最好的。(这假设您可以迭代两次。如果迭代器实际上是惰性计算的包装器……这可能是不可能的。)

    • 如果您正在优化以减少GC,那么“计数优先”可能是最好的,这取决于迭代的细节

    在所有情况下,建议您:

  • 在您花更多时间处理此问题之前,请先分析您的应用程序。在很多情况下,你会发现这根本不值得你努力优化

  • 使用应用程序中的类和典型数据结构,对您正在考虑的两个备选方案进行基准测试


  • 目前,如果
    iterableOfA
    有5000个元素,这将导致对列表的支持数组进行许多调整

    ArrayList
    类的大小调整为与当前大小成比例的新大小。这意味着调整大小的数量是
    O(logN)
    ,而
    N
    列表附加调用的总成本是
    O(N)

    当iterable的大小未知且变化很大时,哪种选择最好

    这取决于你在优化什么

    • 如果您正在优化性能,那么使用
      ArrayList
      可能会更快。即使
      ArrayList
      需要调整备份阵列的大小,它也会使用指数增长模式进行调整。然而,这取决于迭代的开销

    • <> L> > P>如果您对长期内存使用进行优化,请考虑使用<代码> ARAYLISTAB/COD> >其次是代码> Trimtosiz()/<代码> < /P>
    • 如果您正在优化峰值内存使用,那么“计数优先”方法可能是最好的。(这假设您可以迭代两次。如果迭代器实际上是惰性计算的包装器……这可能是不可能的。)

    • 如果您正在优化以减少GC,那么“计数优先”可能是最好的,这取决于迭代的细节

    在所有情况下,建议您:

  • 在您花更多时间处理此问题之前,请先分析您的应用程序。在很多情况下,你会发现这根本不值得你努力优化

  • 使用应用程序中的类和典型数据结构,对您正在考虑的两个备选方案进行基准测试


  • 目前,如果
    iterableOfA
    有5000个元素,这将导致对列表的支持数组进行许多调整


    ArrayList
    类的大小调整为与当前大小成比例的新大小。这意味着调整大小的数量是
    O(logN)
    ,而
    N
    列表附加调用的总成本是
    O(N)

    第三个选项不错。对于获取大小,大多数集合只返回它们内部维护的计数器…它不会遍历整个列表。这取决于实现,但所有java.util.xxx集合类都是这样做的

    如果你知道“iterableOfA”的潜在类型,你可以检查它们的大小

    如果“iterableOfA”是某种自定义实现,而您不确定大小是如何实现的,那么linkedlist会更安全。这是因为您的大小不同,并且调整大小的可能性更高,因此您将无法获得可预测的性能


    也不确定您在填充“B”的集合中执行的操作,您的选择也取决于此。

    第三个选项不错。对于获取大小,大多数集合只返回它们内部维护的计数器…它不会遍历整个列表。这取决于实现,但所有java.util.xxx集合类都是这样做的

    如果你知道“iterableOfA”的潜在类型,你可以检查它们的大小

    如果“iterableOfA”是某种自定义实现,而您不确定大小是如何实现的,那么linkedlist会更安全。那是因为你的身材各不相同
    Iterator<A> itr = iterableOfA.getIterator();
    int size = Iterables.size(iterableOfA); // from Guava
    List<B> list = new ArrayList<>(size);
    // and the rest...
    
    final Iterable<A> iofA ... ;
    Iterable<B> iofB = new Iterable<B>() {
      public Iterator<B> iterator() {
        return new Iterator<B>() {
          private final Iterator<A> _iter = iofA.iterator();
          public boolean hasNext() { return _iter.hasNext(); }
          public B next() { return _iter.next().getB(); }
        };
      }
    };
    
    for (Iterator<E> it = list.iterator(); it.hasNext(); ) {
        E e = it.next();
        if (someCondition(e)) e.remove();
    }