2015-08-19 27 views
5

Tôi đã tạo hai danh sách từ cùng một mảng và sắp xếp một danh sách. Khi tôi cố thay đổi một danh sách, danh sách khác cũng được cập nhật.Đã tạo hai Danh sách từ cùng một mảng, Sửa đổi một Danh sách, thay đổi một Danh sách khác

List<Integer> list = Arrays.asList(ar); 
List<Integer> sorted = Arrays.asList(ar); 
Collections.sort(sorted); 
list.set(0,10000000); //changes sorted also 

Tôi mất một lúc để hiểu, mã được đề cập bên dưới hoạt động.

List<Integer> sorted = new ArrayList<Integer>(Arrays.asList(ar));

Tôi muốn biết lý do tại sao phương pháp tiếp cận đầu tiên của tôi đã không làm việc? Tôi đã tạo hai danh sách riêng biệt, tại sao các thay đổi đang diễn ra ở cả hai. Làm thế nào để java gán giá trị cho các biến ở đây?

+0

'danh sách' và' sắp xếp' đang trỏ đến cùng một mảng, phải không? – Andrew

+1

@AndrewTobilko: nhưng anh ấy chỉ sắp xếp một Danh sách. Tôi sẽ bỏ phiếu này như một câu hỏi thú vị. –

+0

Tôi hơi ngạc nhiên rằng đây có vẻ là lần đầu tiên câu hỏi này được hỏi trên SO vì "vấn đề" cũ như bản thân 'Arrays' (java 1.2). Và tôi nghi ngờ tất cả mọi người đọc (và hiểu) javadoc cho đến bây giờ ... –

Trả lời

11

Từ các tài liệu Java cho Arrays.asList:

Trả về một danh sách kích thước cố định được hỗ trợ bởi các mảng được chỉ định. (Thay đổi danh sách trả về "ghi thông qua" cho mảng.) Phương thức này hoạt động như cầu nối giữa các API dựa trên mảng và dựa trên bộ sưu tập, kết hợp với Collection.toArray(). Danh sách trả về được tuần tự hóa và thực hiện RandomAccess.

Vì vậy, khi bạn thay đổi thứ gì đó trong danh sách, nó "viết" cho mảng nằm dưới, ar, cũng là mảng nằm trong sắp xếp, do đó thay đổi cũng được phản ánh trong sắp xếp.

Ngoài ra, các mã cho asList là:

public static <T> List<T> asList(T... a) { 
    return new ArrayList<T>(a); 
} 

Đây là java.util.Arrays.ArrayList, trong đó có định nghĩa sau đây:

ArrayList(E[] array) { 
    a = Objects.requireNonNull(array); 
} 

Điều quan trọng là a không sao chép, nó là bản gốc mảng. Lớp java.util.ArrayList có constructor sau

public ArrayList(Collection<? extends E> c) { 
    elementData = c.toArray(); 
    size = elementData.length; 
    // c.toArray might (incorrectly) not return Object[] (see 6260652) 
    if (elementData.getClass() != Object[].class) 
     elementData = Arrays.copyOf(elementData, size, Object[].class); 
} 

như vậy trong các nhà xây dựng java.util.ArrayList, chúng ta tạo ra bản sao của mỗi phần tử, và trong java.util.Arrays.ArrayList, chúng tôi thì không.

+2

Xin vui lòng, không trộn lẫn 'java.util.Arrays.ArrayList' và' java.util.ArrayList'. Hành vi này không thay đổi trong Java 8. – Holger

+0

@Holger, cảm ơn! Tôi đã cập nhật bài đăng gốc của mình để bao gồm điểm này. – Sunde

1

Mảng có triển khai riêng của ArrayList mà không tạo một bản sao của mảng từ ToList

1

Một Danh sách là một tập hợp các đối tượng, và cả hai danh sách là bộ sưu tập của các đối tượng tương tự. Câu lệnh set thay đổi một đối tượng và đối tượng được chia sẻ bởi cả hai danh sách.

Tôi không hiểu tại sao phiên bản thứ hai hoạt động.

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