2010-06-15 6 views
31

Tôi có một vài số Set<String> và muốn chuyển đổi từng số này thành một đơn String trong đó mỗi phần tử của Set gốc được phân tách bằng khoảng trắng "". Cách tiếp cận đầu tiên ngây thơ là làm như thế nàyCách nhanh nhất để đặt nội dung của Set <String> vào một chuỗi đơn với các từ được phân tách bằng khoảng trắng?

Set<String> set_1; 
Set<String> set_2; 

StringBuilder builder = new StringBuilder(); 
for (String str : set_1) { 
    builder.append(str).append(" "); 
} 

this.string_1 = builder.toString(); 

builder = new StringBuilder(); 
for (String str : set_2) { 
    builder.append(str).append(" "); 
} 

this.string_2 = builder.toString(); 

Có ai nghĩ cách nhanh hơn, đẹp hơn hoặc hiệu quả hơn để làm điều này không?

+0

http://stackoverflow.com/questions/187676/string-operations-in-java –

Trả lời

51

Với commons/lang bạn có thể làm điều này bằng StringUtils.join:

String str_1 = StringUtils.join(set_1, " "); 

Bạn có thể không thực sự đánh bại đó cho ngắn gọn.

Cập nhật:

Đọc lại câu trả lời này, tôi muốn the other answer regarding Guava's Joiner bây giờ. Trong thực tế, những ngày này tôi không đi gần commons apache.

+2

ngắn gọn, nhưng không linh hoạt. Tôi nhận được "" thay thế cho null cho dù tôi muốn hay không, và không có một lựa chọn bỏ qua null ... đây là lý do tại sao chúng tôi làm Joiner cho ổi (xem câu trả lời khác). –

+0

Tôi thường không có null trong bộ sưu tập của mình, do đó, cách tiếp cận ngắn gọn là tốt cho tôi, nhưng đá ổi! Cảm ơn bạn đã thực hiện điều đó ... –

+0

Vì bạn không mong đợi các giá trị rỗng, bạn muốn joiner của mình phát nổ nếu bạn * đã * có một giá trị rỗng - đó là những gì mà Joiner của Guava thực hiện theo mặc định. :-) –

3

Tôi đang bối rối về việc sao chép mã, tại sao không đưa yếu tố đó vào một hàm lấy một bộ và trả về một chuỗi? Ngoài ra, tôi không chắc rằng có nhiều thứ bạn có thể làm, ngoại trừ có thể cho người xây dựng chuỗi một gợi ý về dung lượng dự kiến ​​(nếu bạn có thể tính toán dựa trên kích thước thiết lập và kỳ vọng hợp lý của độ dài chuỗi). .

Có chức năng thư viện cho điều này, nhưng tôi nghi ngờ chúng hiệu quả hơn đáng kể.

+0

Cảm ơn câu trả lời của bạn! Tôi đã không đặt nó vào một chức năng riêng biệt để làm nổi bật thực tế là tôi đang cố gắng tái sử dụng biến 'builder'. Có lẽ điều đó không quan trọng? –

+2

Nó không quan trọng. Việc thay đổi các biến có thể thực sự khiến bạn gặp khó khăn trong dòng. Thay vào đó, chỉ có các biến nằm ngoài phạm vi khi chúng không còn cần thiết nữa. – Gunslinger47

+0

@Gunslinger, tôi hiểu, cảm ơn! @ Uri, cảm ơn lời khuyên về năng lực ban đầu. –

18

Trái với những commons-lang Seanizer của câu trả lời, nếu bạn đang sử dụng của Google Guava Libraries (mà tôi muốn xem xét các 'người kế nhiệm' để commons-lang, bằng nhiều cách), bạn muốn sử dụng Joiner:

Joiner.on(" ").join(set_1); 

với lợi thế là một vài phương pháp helper để làm những việc như:

Joiner.on(" ").skipNulls().join(set_1); 
// If 2nd item was null, would produce "1, 3" 

hoặc

Joiner.on(" ").useForNull("<unknown>").join(set_1); 
// If 2nd item was null, would produce "1, <unknown>, 3" 

Nó cũng có hỗ trợ để nối trực tiếp vào StringBuilders và Nhà văn, và các niceties như vậy.

+0

Sự khác nhau giữa các thư viện ổi và thư viện sưu tập google là gì? –

+0

sự khác biệt chính là ổi biết về generics và commons/collection không, nhưng ngoài ra: chúng là hai thư viện khác nhau được viết bởi hai nhóm khác nhau giải quyết một số vấn đề tương tự (và một số không tương tự) sử dụng cách tiếp cận khác nhau –

+2

@seanizer, Shervin đã hỏi về guava vs google-bộ sưu tập, không phải là ổi vs commons :) Shervin - ổi chỉ đơn giản là sự thay thế cho bộ sưu tập google. Khi dự án tăng lên trong phạm vi, nó dừng lại bị giới hạn ở những thứ chỉ có bộ sưu tập để thay đổi tên theo thứ tự. bộ sưu tập của google về cơ bản nên được coi là không được chấp nhận, ổi là một thay thế thả xuống với các bản sửa lỗi + nhiều tính năng hơn. – Cowan

3

tôi sử dụng phương pháp này:

public static String join(Set<String> set, String sep) { 
    String result = null; 
    if(set != null) { 
     StringBuilder sb = new StringBuilder(); 
     Iterator<String> it = set.iterator(); 
     if(it.hasNext()) { 
      sb.append(it.next()); 
     } 
     while(it.hasNext()) { 
      sb.append(sep).append(it.next()); 
     } 
     result = sb.toString(); 
    } 
    return result; 
} 
6

tôi không có thư viện StringUtil sẵn (Tôi không có sự lựa chọn hơn mà) để sử dụng tiêu chuẩn Java Tôi đến với điều này ..

Nếu bạn 'tái tin tưởng rằng dữ liệu thiết lập của bạn sẽ không bao gồm bất kỳ dấu phẩy, bạn có thể sử dụng:

mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," "); 

một tập hợp các 'a', 'b', 'c' chuyển đổi qua ToString() để chuỗi "[a , b, c] ".

Sau đó, thay thế dấu câu bổ sung là cần thiết.

Thứ.

+2

Rất tuyệt! Luôn luôn mát mẻ để xem những gì bạn có thể làm với các libs tiêu chuẩn JDK :) –

+0

sạch sẽ, đơn giản, không phụ thuộc vào thư viện do đó không thêm vào trọng lượng ứng dụng - thích nó! –

22

Nếu bạn đang sử dụng Java 8, bạn có thể sử dụng phương pháp native

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements) 

:

Trả về một mới String gồm bản sao của CharSequence yếu tố liên kết với nhau với một bản sao của quy định dấu phân tách. Ví dụ:

Set<String> strings = new LinkedHashSet<>(); 
strings.add("Java"); strings.add("is"); 
strings.add("very"); strings.add("cool"); 
String message = String.join("-", strings); 
//message returned is: "Java-is-very-cool" 

Set thực hiện Iterable, vì vậy chỉ cần sử dụng:

String.join(" ", set_1); 
+0

Đẹp nhất! Bắt đầu sử dụng java 8 gần đây, không biết về điều này. –

2

Điều này có thể được thực hiện bằng cách tạo ra một dòng ra trong cùng bộ và sau đó kết hợp các yếu tố sử dụng một giảm hoạt động như được hiển thị bên dưới (để biết thêm chi tiết về các luồng Java 8 kiểm tra here):

Optional<String> joinedString = set1.stream().reduce(new 
BinaryOperator<String>() { 

    @Override 
    public String apply(String t, String u) { 

     return t + " " + u; 
    } 
}); 
return joinedString.orElse(""); 
3

Có thể giải pháp ngắn hơn:

public String test78 (Set<String> set) { 
    return set. 
     stream() 
     .collect(Collectors.joining(" ")); 
}