Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.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内存分配_Java_Recursion_Stack Overflow - Fatal编程技术网

Java内存分配

Java内存分配,java,recursion,stack-overflow,Java,Recursion,Stack Overflow,我有一个问题一直在思考。以这个特殊的类为例 class A{ private static ArrayList<String> listOne; public Static ArrayList<String> getList() { return this.listOne } } A类{ 私有静态ArrayList-listOne; 公共静态ArrayList getList() { 把这个还给我 } } 假设我有一个类B,它拥有一个方法来

我有一个问题一直在思考。以这个特殊的类为例

class A{

private static ArrayList<String> listOne;

public Static ArrayList<String> getList()
  {
    return this.listOne
  }
}  
A类{
私有静态ArrayList-listOne;
公共静态ArrayList getList()
{
把这个还给我
}
}  
假设我有一个类B,它拥有一个方法来读取listOne的详细信息。要查看arraylist,我需要首先获得列表的大小,以便代码知道arraylist何时结束。我有两种方法可以做到这一点,一种是

int listSize = A.getList().size()
for(int count =0; count < listSize; count++)
{
  // code to read through arraylist
}
int listSize=A.getList().size()
对于(int count=0;count
或者我也可以用它来实现同样的目标

for(int count=0; count < A.getList().size(); count++)
{
  // code to read through arraylist
}
for(int count=0;count

在内存和效率方面,哪种方法更好?此外,假设我正在递归地读取一个非常大的数组。为了简单起见,让我们假设递归读取此数组将导致堆栈溢出异常。在这种情况下,第一个方法理论上会导致堆栈溢出发生得比第二个方法更早,因为每个递归调用的堆栈帧必须保持变量“listSize”的状态吗

查看
javap-verbose的结果:

 0: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
 3: invokevirtual #3                  // Method java/util/ArrayList.size:()I
 6: istore_1
 7: iconst_0
 8: istore_2
 9: iload_2
10: iload_1
11: if_icmpge     27
14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
17: iload_2
18: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
21: iinc          2, 1
24: goto          9
27: iconst_0
28: istore_2
29: iload_2
30: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
33: invokevirtual #3                  // Method java/util/ArrayList.size:()I
36: if_icmpge     52
39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
42: iload_2
43: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
46: iinc          2, 1
49: goto          29
52: return
第一种情况是:

 9: iload_2
10: iload_1
11: if_icmpge     27
14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
17: iload_2
18: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
21: iinc          2, 1
24: goto          9
第二个:

29: iload_2
30: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
33: invokevirtual #3                  // Method java/util/ArrayList.size:()I
36: if_icmpge     52
39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
42: iload_2
43: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
46: iinc          2, 1
49: goto          29
如您所见,它将在每次循环迭代中获得列表及其大小。 但是,这可能会通过JIT进行优化,因此仅从编译的字节码来看结果并不明显

创建自:

import java.io.*;
import java.util.*;

public class Z {

    public static void main(String[] args) throws Exception {
        int listSize = A.getList().size();
        for(int count =0; count < listSize; count++) {
            System.out.println(count);
        }
        for(int count =0; count < A.getList().size(); count++) {
            System.out.println(count);
        }
    }

}

class A{

    private static ArrayList<String> listOne = new ArrayList<>(Arrays.asList("1", "2", "3"));

    public static ArrayList<String> getList()
    {
        return listOne;
    }
}  
import java.io.*;
导入java.util.*;
公共类Z{
公共静态void main(字符串[]args)引发异常{
int listSize=A.getList().size();
对于(int count=0;count
查看
javap-verbose的结果:

 0: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
 3: invokevirtual #3                  // Method java/util/ArrayList.size:()I
 6: istore_1
 7: iconst_0
 8: istore_2
 9: iload_2
10: iload_1
11: if_icmpge     27
14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
17: iload_2
18: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
21: iinc          2, 1
24: goto          9
27: iconst_0
28: istore_2
29: iload_2
30: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
33: invokevirtual #3                  // Method java/util/ArrayList.size:()I
36: if_icmpge     52
39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
42: iload_2
43: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
46: iinc          2, 1
49: goto          29
52: return
第一种情况是:

 9: iload_2
10: iload_1
11: if_icmpge     27
14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
17: iload_2
18: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
21: iinc          2, 1
24: goto          9
第二个:

29: iload_2
30: invokestatic  #2                  // Method A.getList:()Ljava/util/ArrayList;
33: invokevirtual #3                  // Method java/util/ArrayList.size:()I
36: if_icmpge     52
39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
42: iload_2
43: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
46: iinc          2, 1
49: goto          29
如您所见,它将在每次循环迭代中获得列表及其大小。 但是,这可能会通过JIT进行优化,因此仅从编译的字节码来看结果并不明显

创建自:

import java.io.*;
import java.util.*;

public class Z {

    public static void main(String[] args) throws Exception {
        int listSize = A.getList().size();
        for(int count =0; count < listSize; count++) {
            System.out.println(count);
        }
        for(int count =0; count < A.getList().size(); count++) {
            System.out.println(count);
        }
    }

}

class A{

    private static ArrayList<String> listOne = new ArrayList<>(Arrays.asList("1", "2", "3"));

    public static ArrayList<String> getList()
    {
        return listOne;
    }
}  
import java.io.*;
导入java.util.*;
公共类Z{
公共静态void main(字符串[]args)引发异常{
int listSize=A.getList().size();
对于(int count=0;count
两个循环都是相同的。第二个是更好的编码,因为它减少了代码行。 既然您提到需要遍历列表,那么最好使用增强的(for each)for循环


两个循环都是相同的。第二个是更好的编码,因为它减少了代码行。 既然您提到需要遍历列表,那么最好使用增强的(for each)for循环


关于哪种方法更有效,我认为它们不会有任何明显的区别。正如Germann所说,根据JVM的不同,编译器甚至会对此进行优化。所以不要担心这个微不足道的差别

我个人将使用第二种方法,因为它的代码行较少,而且我很懒

然而,为什么两者都不使用呢

有一个超级酷的选择,它的名字是。。。乔恩·塞纳是增强型for循环

让我们将其与普通for循环进行比较:

正常:

for (int i = 0 ; i < A.getList().size() ; i++ {

}
看这多好啊

这两个for循环的主要区别在于

  • normal for循环只是一种带有初始化和增量的while循环
  • 增强的for循环调用
    .iterator().hasNext()
    .iterator().next()
  • 要使用普通for循环,您需要知道列表的大小
  • 您的列表只需要实现
    Iterable
    ,可能还需要实现
    Iterator
    ,以使用增强的for循环。不需要尺寸
增强的for循环具有以下限制:

  • 不能同时在两个数组中循环
  • 如果想知道列表的索引,最好使用普通for循环,因为多次调用
    indexOf
    不是很有效

关于哪种方法更有效,我认为它们不会有任何明显的区别。正如Germann所说,根据JVM的不同,编译器甚至会对此进行优化。所以不要担心这个微不足道的差别

我个人将使用第二种方法,因为它的代码行较少,而且我很懒

然而,为什么两者都不使用呢

有一个超级酷的选择,它的名字是。。。乔恩·塞纳是增强型for循环

让我们将其与普通for循环进行比较:

正常:

for (int i = 0 ; i < A.getList().size() ; i++ {

}
看这多好啊

这两个for循环的主要区别在于

  • normal for循环只是一种带有初始化和增量的while循环
  • 增强的for循环调用
    .iterator().hasNext()
    .iterator().next()
  • 要使用普通for循环,您需要知道列表的大小
  • 您的列表只需要实现
    Iterable
    ,可能还需要实现
    Iterator
    ,以使用增强的for循环。不需要尺寸
增强的for循环具有以下l