2009-10-29 31 views
9

Tôi chưa bao giờ tìm được cách làm gọn gàng (er).Cách thanh lịch nhất để nối một danh sách các giá trị với dấu phân cách bằng Java là gì?

Giả sử tôi có danh sách/mảng chuỗi.

abc 
def 
ghi 
jkl 

Và tôi muốn nối chúng thành một chuỗi duy nhất giới hạn bởi một dấu phẩy như sau:

abc,def,ghi,jkl 

Trong Java, nếu tôi viết một cái gì đó như thế này (tha thứ cú pháp),

String[] list = new String[] {"abc","def","ghi","jkl"}; 
String str = null; 
for (String s : list) 
{ 
    str = str + s + "," ; 
} 

System.out.println(str); 

tôi sẽ nhận được

abc,def,ghi,jkl, //Notice the comma in the end 

Vì vậy, tôi phải viết lại vòng trên cho vòng lặp như sau

... 
for (int i = 0; i < list.length; i++) 
{ 
    str = str + list[i]; 
    if (i != list.length - 1) 
    { 
    str = str + ","; 
    } 
} 
... 

Điều này có thể được thực hiện một cách thanh lịch hơn trong Java không?

Tôi chắc chắn sẽ sử dụng một StringBuilder/Buffer cho hiệu quả, nhưng tôi muốn minh họa trường hợp tại điểm mà không quá dài dòng. Bằng cách thanh lịch, tôi có nghĩa là một giải pháp tránh được sự kiểm tra xấu xí (?) if bên trong vòng lặp.

+1

Xem http://stackoverflow.com/questions/205555/the-most-sophisticated-way-for-creating-comma-separated-strings-from-a -collection/205712 # 205712 – gimel

+0

http://stackoverflow.com/questions/285523 – toolkit

Trả lời

10

Đây là phiên bản của tôi: Java Tricks: Fastest Way to Collecting Objects in a String

StringBuilder buffer = new StringBuilder(); 
String delim = ""; 
for (Object o: list) 
{ 
    buffer.append (delim); 
    delim = ", "; // Avoid if(); assignment is very fast! 
    buffer.append (o); 
} 
buffer.toString(); 

Là một tiền thưởng thêm: Nếu mã của bạn trong vòng lặp là phức tạp hơn, sau đó phương pháp này sẽ tạo ra một kết quả chính xác mà không cần phức tạp if() s.

Cũng lưu ý rằng với CPU hiện đại, nhiệm vụ sẽ chỉ xảy ra trong bộ đệm (hoặc có thể chỉ trong sổ đăng ký).

Kết luận: Mặc dù mã này trông kỳ lạ ngay từ cái nhìn đầu tiên nhưng nó có nhiều lợi thế.

+1

Nó không phải là rất đẹp - làm cho một khởi tạo delim mỗi iteration. –

+1

Vui lòng cung cấp giải pháp của bạn trong trường hợp xóa bài đăng trên blog của bạn. – guerda

+0

Làm thế nào nếu() không nhanh? –

2

Nhìn đây:

http://snippets.dzone.com/posts/show/91

cho một cuộc thảo luận đầy đủ về chủ đề này.

+0

Cảm ơn bạn đã liên kết. Tôi đang tìm kiếm một cách tiếp cận thanh lịch hơn (có lẽ một cách liên quan đến ít dòng mã hơn). Hiệu suất, trong trường hợp của tôi, không phải là một mối quan tâm lớn. – Rahul

+0

Tôi không thích kiểm tra trong giao diện khi bạn có thể làm điều đó bên ngoài –

-1

Tôi sẽ sử dụng StringBuffer để triển khai tính năng này. String là bất biến nên mỗi khi bạn concat hai String s, một đối tượng mới được tạo ra.

hiệu quả hơn là việc sử dụng StringBuffer:

String[] list = new String[] {"abc","def","ghi","jkl"}; 
StringBuffer str = new StringBuffer(); 
for (String s : list) { 
    str.append(s); 
    str.append(","); 
} 
str.deleteCharAt(str.length()); 
System.out.println(str); //automatically invokes StringBuffer.toString(); 
+2

: p Bạn đã quên dấu phẩy cuối cùng ... –

+0

Lỗi đúng ... đã sửa. – guerda

+1

Bạn không nên sử dụng StringBuffer, nơi nó không cần thiết, đó là chủ đề an toàn và chậm, tôi sẽ sử dụng StringBuilder thay thế. Bạn cũng phải xóa dấu phẩy cuối cùng – codevour

3
StringBuilder builder = new StringBuilder(); 
for (String st: list) { 
    builder.append(st).append(','); 
} 
builder.deleteCharAt(builder.length()); 
String result = builder.toString(); 

Không sử dụng '+' cho contacenations chuỗi. Nó chậm.

+0

Bỏ lỡ đúng parathesis trên dòng 5;) – guerda

+0

Cảm ơn bạn đã sửa! –

+0

Tôi thích điều này! =) – codevour

-1
for (int i = 0; i < list.length-1; i++) { 
    str = str + list[i]; 
    str = str + ",";  
} 
str = str + list[list.length-1] 
+0

Sử dụng ghép nối chuỗi không phải là rất nhanh. Mã này cũng khó đọc Tôi nghĩ rằng – codevour

+1

tôi biết chuỗi nối isent nhanh thats không phải là điểm và có ít của nó chỉ có thể đọc được chỉ ra các tùy chọn khác để làm những gì OP hỏi – Peter

+0

Bạn đã thử các mã với một danh sách sản phẩm nào? –

2

Tôi muốn đặt cược rằng có một số lớp học có tên là "StringUtil", "StringsUtil", "Strings" hay bất cứ điều gì cùng những dòng trên classpath của bất kỳ dự án Java vừa. Nhiều khả năng, bất kỳ người nào trong số họ sẽ cung cấp chức năng tham gia.Dưới đây là một số ví dụ tôi đã tìm thấy trong dự án của tôi:

org.apache.commons.lang.StringUtils.join(...) 
org.apache.wicket.util.string.Wicket.join(...) 
org.compass.core.util.StringUtils.arrayToDelimitedString(...) 

Như bạn có thể muốn thoát khỏi một số phụ thuộc bên ngoài trong tương lai, bạn có thể muốn một cái gì đó như thế này:

public static final MyStringUtils { 
    private MyStringUtils() {} 

    public static String join(Object[] list, String delim) { 
     return org.apache.commons.lang.StringUtils.join(list, delim); 
    } 
} 

Bây giờ đó là những gì tôi gọi là "thanh lịch";)

+0

Tại sao bạn sẽ tạo một lớp mới chỉ để bọc một cuộc gọi đến org.apache.commons.lang.StringUtils.join? Làm thế nào để loại bỏ các phụ thuộc bên ngoài? –

+1

@DerekSpringer nó không loại bỏ sự phụ thuộc bên ngoài. Ẩn phụ thuộc vào một cái gì đó như MyStringUtils chỉ làm cho nó dễ dàng hơn để thay đổi việc thực hiện. Kết quả là, người ta có thể loại bỏ sự phụ thuộc bên ngoài bằng cách thay đổi lớp MyStringUtils chỉ. – sfussenegger

11

Sử dụng Guava's (formerly google-collections) joiner class:

Joiner.on(",").join(list) 

Xong.

+2

+1 cho bộ sưu tập trên google. Vâng, vâng, tôi biết - 'một sự phụ thuộc bên ngoài chỉ để tham gia chuỗi?!?!' - nhưng nó có thể làm cho mã của bạn ngắn hơn rất nhiều + biểu cảm hơn, nếu bạn tìm hiểu API, nó sẽ tự trả tiền trong một giờ. :) – Cowan

+2

một khi bạn nhìn vào api, bạn sẽ sử dụng ist cho nhiều hơn là chỉ tham gia chuỗi. –

+0

@Andreas, đề xuất cho những gì khác nó là tốt cho? –

0

kiểm tra nếu điều này rất hữu ích:

List<Integer> numbers=new ArrayList<Integer>(); 
    numbers.add(1); 
    numbers.add(2); 
    numbers.add(3); 
    numbers.add(4); 
    numbers.add(5); 
    numbers.add(6); 
    String str = " "; 
    for(Integer s:numbers){ 
    str=str+s+" , "; 
    } 
    System.out.println(str.substring(0,str.length()-2)); 
Các vấn đề liên quan