The trigger was I read the source of ArrayList. I wrote what I was interested in I read the source of ArrayList, but I read it further and was interested is.
"I don't understand the difference between LL.116-126 EMPTY_ELEMENT DATA and DEFAULTCAPACITY_EMPTY_ELEMENTDATA. Do you understand if you read on? However, the latter javadoc properly says, "This is the difference." Such comments are important. But I still don't understand it. 』\
That's right. I know what I want to do, but I don't understand the intention of dividing it into two variables. Well, I was curious and checked it.
Then, the first stage correction was found. First, lazy evaluation of the default constructor. Certainly, if it is the source of the old JDK, when I look at the constructor, I feel that I immediately understood how much size should be secured by the initial value. It's an empty array. This is the one that fixed it. 8011200: (coll) Optimize empty HashMap and ArrayList
public ArrayList() {
// this(10);
super();
this.elementData = EMPTY_ELEMENTDATA;
}
Instead of allocating 10 arrays at first, make it empty and expand it when added. This is fine.
Next, a second-stage fix was found. Here, DEFAULTCAPACITY_EMPTY_ELEMENTDATA is added. 8035584: ArrayList(c) should avoid inflation if c is empty
When an empty list is passed with public ArrayList (Collection <? extends E> c) {, c.toArray (); is called and the number of instances increases steadily. So, when size == 0, I set this.elementData = EMPTY_ELEMENTDATA ;. I understand that.
So why did you change this.elementData = EMPTY_ELEMENTDATA; to this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; when public ArrayList () {? Well, I don't know.
Judging from both modifications, when new ArrayList () was done, it was originally new ArrayList (10). But now I'm substituting an empty array. On the other hand, when new ArrayList (0) is executed, an empty array is assigned. The same is true when passing an empty list to the constructor.
In other words, when adding for the first time after creating an instance, DEFAULTCAPACITY_EMPTY_ELEMENTDATA and EMPTY_ELEMENTDATA are assigned separately to distinguish whether it was created with new ArrayList () or new ArrayList (0). ..
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
This difference between 0 and 10 (DEFAULT_CAPACITY) is ignored when ensureCapacity (5) is called because the buffer size is originally 10 for new ArrayList (), and from buffer size = 0 for new ArrayList (0). The decision was to increase the buffer size to 5.
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
When this max is also new ArrayList (), even if you try to add to buffer size = 0 and set buffer size = 1, it means that buffer size = 10 (DEFAULT_CAPACITY) suddenly.
Don't fix another case together with the fix "ArrayList (c) should avoid inflation if c is empty". Maybe it's written somewhere.
Recommended Posts