Java:是否缓存了Arraylist的get方法?

时间:2017-10-18 10:56:10

标签: java performance memory arraylist get

Arraylist对象是否将最后请求的值存储在内存中,以便下次更快地访问它?或者我自己需要这样做吗?

或者更具体地说,就性能而言,最好是这样做:

for (int i = 0; i < myArray.size(); i++){
    int value = myArray.get(i);

    int result = value + 2 * value - 5 / value;
}

而不是这样做:

for (int i = 0; i < myArray.size(); i++)
    int result = myArray.get(i) + 2 * myArray.get(i) - 5 / myArray.get(i);

2 个答案:

答案 0 :(得分:2)

就性能而言,一点都无所谓。不,ArrayList不会缓存任何内容,尽管JITted最终结果可能是另一个问题。

如果您想知道要使用哪个版本,请使用第一个版本。它更清楚。

答案 1 :(得分:1)

您可以通过查看实际来源自己回答您的(第一个)问题:

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

所以:不,没有缓存发生,但你也可以看到在性能方面没有太大影响,因为get方法基本上只是对数组的访问。

但出于某些原因避免多次通话仍然很好:

  • int result = value + 2 * value - 5 / value更容易理解(即在计算中意识到您使用相同的值三次)
  • 如果您以后决定更改基础列表(例如更改为LinkedList),最终可能会对性能产生影响,然后必须更改代码才能解决问题。
  • 只要您不同步对列表的访问权限,get(index)的重复调用实际上可能会返回不同的值,如果两次调用之间发生了set(index, value)的调用(即使在小的源中)像这样的街区,有可能发生 - BTST)

第二点在如何访问列表的所有值方面也有一个结果,如果您要迭代列表中的所有元素,则会导致决定完全避免list.get(i)。在这种情况下,最好使用Iterator或流:

您的代码将如下所示:

Iterator it = myArray.iterator();
while (it.hasNext()) {
    int value = it.next();

    int result = value + 2 * value - 5 / value;
}
尝试通过特定索引访问其中的元素时,

LinkedList非常慢,但是从一个元素到下一个元素的迭代速度非常快,因此Iterator返回的LinkedList使用了虽然Iterator返回的ArrayList只是访问内部数组(无需执行重复的范围检查调用,您可以在上面的get - 方法中看到