Trên Tue, ngày 9 tháng 3 năm 2010 lúc 03:02, Kevin L. Stern đã viết:
Tôi đã thực hiện một tìm kiếm nhanh và có vẻ như Java thực sự là phần bổ sung của hai. Tuy nhiên, xin vui lòng cho phép tôi chỉ ra rằng, nói chung, loại mã này làm tôi lo lắng vì tôi hoàn toàn mong đợi rằng đến một lúc nào đó sẽ có người đi cùng và làm chính xác những gì Dmytro đề xuất; nghĩa là, ai đó sẽ thay đổi:
if (a - b > 0)
đến
if (a > b)
và toàn bộ con tàu sẽ chìm. Cá nhân tôi muốn tránh những điều tối nghĩa như làm cho số nguyên tràn ra làm cơ sở thiết yếu cho thuật toán của tôi trừ khi có lý do chính đáng để làm như vậy. Nói chung, tôi muốn tránh tràn hoàn toàn và làm cho kịch bản tràn hơn rõ ràng hơn:
if (oldCapacity > RESIZE_OVERFLOW_THRESHOLD) {
// Do something
} else {
// Do something else
}
Đó là một điểm tốt.
Trong ArrayList
chúng tôi không thể làm điều này (hoặc ít nhất là không tương thích), vì
ensureCapacity
là API công khai và thực sự đã chấp nhận các số âm là yêu cầu cho khả năng tích cực không thể thỏa mãn.
API hiện tại được sử dụng như thế này:
int newcount = count + len;
ensureCapacity(newcount);
Nếu bạn muốn tránh tràn, bạn sẽ cần thay đổi thành một thứ ít tự nhiên hơn như
ensureCapacity(count, len);
int newcount = count + len;
Dù sao, tôi đang giữ mã có ý thức tràn, nhưng thêm nhiều bình luận cảnh báo và tạo ra mảng lớn "ngoài luồng" để
ArrayList
mã đó giờ trông như sau:
/**
* 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 được tái sinh.
Martin
if (newCapacity - minCapacity < 0)
tốt hơnif (newCapacity < minCapacity)
về mặt ngăn chặn tràn?