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. Or rather, it's so long that I can't read it all at once ...
By the way, did ArrayList have methods such as removeAll and retainAll? If you look at javadoc immediately, there is none. I'm always looking at JDK 6. So if you look at JDK 7. But the method doesn't have @since 1.7! !! !! Well, I think that @since was attached to each method in the Sun Micro era, but is it appropriate now?
If you take a second look and look at the source, it's actually batchRemove. I was particularly interested in this comment. "But I'm not rolling back the contents. 』\
It is written in javadoc that when c.contains issues a nullpo, batchRemove issues a nullpo and removeAll and retainAll issue a nullpo. Well, it's okay if the specification is that an exception will occur, but the problem is that the data is corrected until null appears in the list, and after null, the exception appears with the data as it is! If you get an exception, revert to the original data.
According to Collections contains NullPointerException-if the specified element is null and this collection does not allow null elements (optional) It seems that. Of course, ArrayList contains null. Therefore, passing an ArrayList to removeAll or retainAll does not result in a nullpo.
So what is a collection that doesn't allow nulls? looked for. For example, that is TreeSet. According to TreeSet contains NullPointerException-if the specified element is null and this set uses natural ordering or its comparator does not allow null elements.
In other words, for an ArrayList containing null, if you pass a TreeSet to removeAll or retainAll, nullpo will appear and the data will be halfway.
Forget about the current specification of Nullpo, what do the original removeAll and retainAll want to do? removeAll wants to remove the specified collection, retainAll wants to keep the specified collection. I think it doesn't really matter if the collection allows or doesn't allow nulls.
In other words, when you pass a collection that does not allow nulls to removeAll, it will never contain nulls, so the nulls in the ArrayList will remain. On the contrary, when you pass a collection that does not allow nulls to retainAll, nulls in ArrayList always disappear because nulls are never included in them.
Enclose c.contains in try-catch. If complement == false in catch, elementData [w ++] = elementData [r] ;.
for (; r < size; r++) {
try {
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} catch (NullPointerException e) {
if (!complement)
elementData[w++] = elementData[r];
}
}
~~~
No need for finally after that.
r ==It loops to size, so if(r != size) {No need.
if (w != size) {Remains as it is.
Of course, besides ArrayList, there seems to be a lot of AbstractCollection and so on.
##bonus
『L.499-500 System.arraycopy()Then, I wonder if src and dst are properly evacuated. Otherwise, this code would overwrite the index you copy later.
System.arraycopy(elementData, index+1, elementData, index, numMoved);』
As expected, the JDK in the world will naturally consider such a thing.
(That? srcPos>Since it is dstPost, there is no problem copying it from the front. srcPos<If you copy from the front in dstPos, it will overwrite itself, so copy from the back)
A description of the System arraycopy.
"If the arguments src and dest are the same array object, for example, first srcPos to srcPos+length-Copy the elements up to 1 into a temporary array with a number of elements of length, then move the contents of the temporary array from destPos to destPos in the destination array.+length-Copy to 1. 』\
Yeah yeah ehhhhh. It's a lie. I'm copying it temporarily. Are you serious. Copy from the front even with that Z80(LDIR)And copy from behind(LDDR)I'm preparing.
[Z80/Block instruction](https://ja.wikipedia.org/wiki/Z80#.E3.83.96.E3.83.AD.E3.83.83.E3.82.AF.E5.91.BD.E4.BB.A4)
This means that if the array is the same, it will be copied twice, so it is more memory efficient to loop by yourself and conditionally branch the copy from the front and the copy from the back. It's a hassle.
ArrayList.add(int,E)Or ArrayList.remove(int)I usually do array copy. Well, I don't use it like this.
Recommended Posts