9 Mart 2010 Salı, 03:02, Kevin L. Stern şunu yazdı:
Hızlı bir arama yaptım ve Java gerçekten iki tamamlayıcı tabanlı görünüyor. Yine de, genel olarak, bu tür bir kodun beni endişelendirdiğini belirtmeme izin verin, çünkü bir noktada birisinin gelip tam olarak Dmytro'nun önerdiğini yapmasını bekliyorum; yani, birisi değişecek:
if (a - b > 0)
için
if (a > b)
ve tüm gemi batacak. Şahsen, bunun için iyi bir neden olmadığı sürece, tamsayı taşmasını algoritmam için temel bir temel haline getirmek gibi belirsizlerden kaçınmak istiyorum. Genel olarak, taşmayı tamamen önlemeyi ve taşma senaryosunu daha açık hale getirmeyi tercih ederim:
if (oldCapacity > RESIZE_OVERFLOW_THRESHOLD) {
// Do something
} else {
// Do something else
}
İyi bir nokta.
In ArrayList
çünkü biz, (ya da en azından değil uyuşan) bunu yapamaz
ensureCapacity
bir genel API ve etkin bir şekilde zaten memnun olamaz olumlu kapasite için istekleri gibi negatif sayılar kabul eder.
Mevcut API şu şekilde kullanılır:
int newcount = count + len;
ensureCapacity(newcount);
Taşmayı önlemek istiyorsanız, daha doğal bir şeye geçmeniz gerekir.
ensureCapacity(count, len);
int newcount = count + len;
Her neyse, taşma bilinçli kod tutuyorum, ancak daha fazla uyarı yorumları ekleyerek ve " ArrayList
kod dizisi şimdi" gibi görünüyor böylece büyük dizi oluşturma "out-astar"
:
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
// Overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// Overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
Webrev yeniden oluşturuldu.
kırlangıç
if (newCapacity - minCapacity < 0)
iyiif (newCapacity < minCapacity)
?