2011-01-31 24 views
6

Tôi không thể modyfing yếu tố Danh sách theo cách này:Iteration của Danh sách <String> với modyfing Chuỗi

for (String s : list) 
{ 
    s = "x" + s; 
} 

Sau khi thực thi mã này yếu tố của danh sách này không thay đổi Làm thế nào để đạt được lặp đi lặp lại với modyfing thông qua Danh sách trong đơn giản nhất đường.

Trả lời

2

Các chuỗi Java không thay đổi được, do đó chúng không thể sửa đổi được. Hơn nữa, nếu bạn muốn sửa đổi danh sách, hãy sử dụng giao diện trình lặp.

+1

Chỉ sửa đổi giao diện Iterator cho phép xóa. Mặt khác, giao diện ListIterator đã thiết lập các phương thức() và add(). –

+0

Bạn đang phải tất nhiên, làm rõ tốt. –

11

String đối tượng không thay đổi, bạn không thể thay đổi giá trị bạn đang lặp lại. Hơn nữa, bạn không thể sửa đổi danh sách mà bạn đang lặp lại trong vòng lặp như vậy. Cách duy nhất để làm điều này là để lặp qua các chỉ số danh sách với một vòng lặp tiêu chuẩn hoặc sử dụng giao diện ListIterator:

for (int i = 0; i < list.size(); i++) 
{ 
    list.set(i, "x" + list.get(i)); 
} 

for (ListIterator i = list.listIterator(); i.hasNext();) 
{ 
    i.set("x" + i.next()); 
} 
+0

Không, sử dụng chỉ mục danh sách không phải là cách duy nhất và truy cập ví dụ: một danh sách được liên kết dài với chỉ số phần tử có thể hoạt động rất kém. Nếu bạn muốn lặp lại và đồng thời sửa đổi một danh sách, sử dụng một Iterator hoặc ListIterator là tốt hơn. – jarnbjo

+0

vì vậy tôi trở lại đây như tôi đã nghĩ đến vòng lặp tiêu chuẩn. – j2j

+0

@jarnbjo: Bạn nói đúng; Tôi chưa xong. Tôi bao gồm cả hai phương pháp. – Gabe

1

Trong vòng lặp của bạn bạn chỉ cần sửa đổi bản sao cục bộ của String. Một lựa chọn tốt hơn là sử dụng trình vòng lặp của danh sách và thay thế vị trí hiện tại của danh sách.

Chỉnh sửa, Rất tiếc, cách để làm chậm.

1

Bạn không thể sửa đổi một yếu tố String của một List theo cách đó, nhưng một StringBuilder sẽ chỉ làm việc tốt:

for (StringBuilder sb : list) sb.append("x"); 

Điều này cũng đúng đối với nguyên thủy khác vs các tình huống tham khảo và cho-mỗi vòng lặp. Trong vòng lặp, Iterable là không thay đổi, nhưng trạng thái của các mục không phải là nguyên thủy (như String) không có trạng thái và do đó bạn chỉ sửa đổi bản sao cục bộ, nhưng tham chiếu có thể có trạng thái và do đó bạn có thể thay đổi chúng thông qua bất kỳ phương pháp đột biến nào mà họ có thể có (ví dụ: sb.append("x")).

3

Strings là những con thú bất biến, vì vậy tôi có thể khuyên bạn nên làm theo triết lý này và tạo danh sách mới thay vì sửa đổi một:

List<String> mappedList = new ArrayList<String>(); 

for (String s : list) { 
    mappedList.add("x" + s); 
} 

Tôi tin rằng, điều này sẽ làm cho mã của bạn dễ dàng hơn để hiểu và duy trì.

+0

ý tưởng thú vị. – j2j

+0

Danh sách có thể sửa đổi, do đó không cần phải tạo một danh sách mới. – finnw

+0

@finnw: bạn có thể giả vờ rằng nó không thể sửa đổi được :) hoặc nếu bạn muốn, bạn có thể làm cho nó không thể sửa đổi như sau: 'Collections.unmodifiableList (list)'. Tôi chỉ khuyến khích trong câu trả lời này để viết thêm mã hiệu ứng phụ miễn phí. – tenshi

2

Như những người khác đã chỉ ra:

  • Bạn không thể sửa đổi chuỗi trong Java, vì vậy s = "x" + s sẽ tạo ra một chuỗi mới (mà sẽ không được chứa trong danh sách)
  • Thậm chí nếu bạn có thể, biến số s là một biến cục bộ, mà khi được gán cho, không ảnh hưởng đến các giá trị chứa trong danh sách.

Giải pháp là trong trường hợp này sử dụng một StringBuilder đại diện cho một chuỗi mà bạn thể thực sự sửa đổi, hoặc sử dụng một ListIterator như @ Michael Borgwardt và @jarnbjo chỉ ra.


Sử dụng một StringBuilder:

List<StringBuilder> someStrings = new LinkedList<StringBuilder>(); 
someStrings.add(new StringBuilder("hello")); 
someStrings.add(new StringBuilder("world")); 

for (StringBuilder s : someStrings) 
    s.insert(0, "x"); 

Sử dụng một ListIterator:

List<String> someStrings = new LinkedList<String>(); 
someStrings.add("hello"); 
someStrings.add("world"); 

for (ListIterator<String> iter = someStrings.listIterator(); iter.hasNext();) 
    iter.set("x" + iter.next()); 

ideone.com demo

+0

Tôi thích sử dụng 'for' với các trình vòng lặp (chia thành nhiều dòng). 'while' tôi cũng giống nhau, nhưng trình lặp có một phạm vi chồng chéo. Và niềng răng, tất nhiên. –

+0

Ah, điểm tốt. – aioobe

3

Something như thế này nên làm như jo b:

public static void main(String[] args) throws Exception { 
    final List<String> lst = Arrays.asList("a", "b", "c"); 
    for(final ListIterator<String> iter = lst.listIterator(); iter.hasNext();) { 
     final String s = iter.next(); 
     iter.set(s + "x"); 
    } 
    System.out.println(lst); 
} 
+1

Tại sao khai báo một biến địa phương bổ sung 's', và tại sao làm cho nó' cuối cùng'? – aioobe

+1

@aioobe: Không có thói quen; Tôi làm cho nó một điểm để tuyên bố tất cả mọi thứ như 'final' trừ khi cần thiết khác. Tương tự với các biến. Thêm vào đó, tôi thích làm cho những người thực hiện tối ưu hóa sớm. ;) –

+0

Hahah, đủ công bằng! – aioobe

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