2010-10-18 35 views
5

Tôi có một ArrayList để lưu trữ một số dữ liệu, nhưng bất cứ khi nào tôi loại bỏ một mục khỏi danh sách, kích thước không giảm, ngay cả khi tôi gọi ArrayList.trimToSize() . Điều này gây ra cho tôi nullPointerExceptions.Java ArrayList.remove() không giảm kích thước của ArrayList

Làm cách nào tôi có thể xóa một mục khỏi ArrayList và có kích thước của danh sách() thu nhỏ cho phù hợp?

EDIT: Được rồi, đây là mã. Đây là một chút nền bạn cần phải biết, vì tôi không thể đăng tất cả các mã. Tôi có một ArrayList gọi là _dataHeap và một HashMap gọi là _dataMap. ArrayList là một Heap nhị phân có chứa một đối tượng "có thể tìm thấy", có một khóa. HashMap liên kết từ một khóa tới chỉ mục của đối tượng trong ArrayList. Đây là một mục trong hàng đợi có thể được tìm thấy theo mục bằng cách sử dụng HashMap hoặc bằng chỉ mục sử dụng ArrayList. Khóa có thể là bất kỳ đối tượng nào, miễn là nó là duy nhất cho mọi mục trong hàng đợi.

Tôi đã sửa lỗi dòng này theo dòng và Heap chứa đối tượng, ngay cả xuống mã băm. Vấn đề là, Object không bao giờ bị xóa khỏi ArrayList. Điều này phải có nghĩa là _dataMap.get (element.getKey()) không trỏ đến vị trí cần thiết. Tôi đã kiểm tra nó mặc dù, tôi đã sử dụng một đối tượng thử nghiệm bên ngoài thực hiện của tôi mà bản đồ từ một String đến một đối tượng tùy chỉnh với String là một khóa.

Tôi tạo một đối tượng, với chuỗi "một" làm khóa của nó. Tôi chèn nó, sau đó cố gắng loại bỏ nó. Tôi đã bước qua điều này, và tất cả mọi thứ kiểm tra, ngoại trừ một điều: Các đối tượng không bao giờ được gỡ bỏ từ hàng đợi. Nó có cùng một Hashcode, cùng Key, mọi thứ. Nó được loại bỏ khỏi bản đồ tốt, nhưng không phải từ ArrayList.

Dưới đây là phương pháp loại bỏ:

public T remove(T element) { 
    //We'll need this data to return the proper value 
    T t = _dataHeap.get(_dataMap.get(element.getKey())); 
    /* 
    * this Swap() call is used to swap our target with the end 
    * of the arraylist. This means that whenever we remove it, 
    * we don't have a change in indexes of the other nodes. 
    * After that, we downHeapify() to fix the whole graph back 
    * to it's functional state. 
    */ 
    swap(_dataMap.get(element.getKey()),length()-1); 
    //Remove from the Heap 
    _dataHeap.remove(_dataMap.get(element.getKey())); 
    _dataHeap.trimToSize(); 
    //Remove from the Map 
    _dataMap.remove(element.getKey()); 
    downHeapify(); 
    return t; 

Tôi hy vọng điều này mang đến cho bạn một ý tưởng tốt hơn về những gì tôi đang làm sai.

EDIT THE SECOND: Holy crap Cuối cùng tôi đã sửa nó! Tôi đã kéo _dataHeap.get (element.index) vào biến riêng của nó. Điều đó giải quyết mọi thứ!

+0

Bạn có thể đăng mã bạn đang sử dụng không? – highlycaffeinated

+4

Bạn không cần phải gọi 'trimToSize()' và 'remove()' _should_ cập nhật đúng kích thước của danh sách. Có lẽ bạn có thể đăng một [SSCCE] (http://sscce.org/) để minh họa vấn đề? –

Trả lời

4

Nghe có vẻ như tôi không thực sự xóa bất kỳ thứ gì. Giá trị trả lại của cuộc gọi remove của bạn là gì?

Nếu bạn đang sử dụng remove(int) giá trị trả về phải là giá trị không. Nếu sử dụng remove(Object), kết quả phải đúng. Nếu không bạn đã không thực sự loại bỏ bất cứ điều gì. Cố gắng xóa phần tử không tồn tại không phải là lỗi, chỉ trả về null hoặc false.

+0

Bạn có thể đang ở một thứ gì đó ngay tại đó. Tôi chỉ cần kiểm tra, với một bản in của ArrayList.contains (mục) trước và sau khi loại bỏ ... và cả hai đều là sai. Bằng cách nào đó nó không thêm vào danh sách đúng. – digiholic

+1

Vì vậy, bạn không thực sự xóa bất kỳ thứ gì. Hoặc là Mike đúng và bạn đã quên ghi đè 'bằng' trên một lớp tùy chỉnh hoặc đối tượng bạn đang cố xóa không bao giờ được thêm (hoặc đã bị xóa trước đây). –

6

Như Bemace đã nói, hãy kiểm tra xem có xóa tác phẩm theo ý bạn không. Tôi đặt cược tiền mà phương thức equals() của bạn trên đối tượng bạn đang sáng tác không hoạt động như thế nào bạn mong đợi nó, bởi vì bạn đã không ghi đè lên nó.

Hơn nữa, sau khi bạn ghi đè bằng, hãy cẩn thận để ghi đè hashCode. Nó sẽ giúp bạn tiết kiệm một câu hỏi SO khi đối tượng của bạn không làm việc với HashMaps. :)

Mẹo: Hãy xem xét sử dụng JUnit. Nó sẽ thổi những lỗi nhỏ này ra khỏi nước, làm cho nó rõ ràng với bạn khi một cái gì đó không hoạt động như thế nào bạn mong muốn. Rất khó để bỏ qua một điểm màu đỏ tươi trên thanh màu xanh lá cây xinh đẹp của bạn.

+3

Re: trọng bằng và hashcode, phải đọc này: http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java –

+0

Được rồi, tôi chỉ thay đổi bằng và Hashcode, nhưng vẫn còn một vấn đề . Tôi không thể tìm ra điều này đúng lúc, vì vậy tôi sẽ sửa nó nhanh chóng, thay vì xóa, tôi sẽ thay thế nó bằng null và kiểm tra các giá trị rỗng trước khi thực hiện. – digiholic

+0

Đăng một số mã. Chúng ta có thể giải quyết nó nhanh chóng. – Mike

Các vấn đề liên quan