2009-11-26 20 views
66

Tôi đã kiểm tra các câu hỏi khác; câu hỏi này tập trung vào giải quyết câu hỏi cụ thể này một cách hiệu quả nhất.Java - Tạo một thể hiện String mới với độ dài được chỉ định và được lấp đầy với các ký tự cụ thể. Giải pháp tốt nhất?

Đôi khi bạn muốn tạo một chuỗi mới có độ dài được chỉ định và với ký tự mặc định sẽ làm đầy toàn bộ chuỗi.

tức là, sẽ thật tuyệt nếu bạn có thể làm new String(10, '*') và tạo Chuỗi mới từ đó, với độ dài 10 ký tự đều có dấu *.

Vì hàm tạo như vậy không tồn tại và bạn không thể mở rộng từ chuỗi, bạn có thể tạo lớp trình bao bọc hoặc phương thức để làm điều này cho bạn.

Tại thời điểm này tôi đang sử dụng này:

protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) { 
    char[] array = new char[length]; 
    int pos = 0; 
    while (pos < length) { 
     array[pos] = charToFill; 
     pos++; 
    } 
    return new String(array); 
} 

Nó vẫn còn thiếu bất kỳ kiểm tra (ví dụ, khi chiều dài là 0 nó sẽ không làm việc). Tôi đang xây dựng mảng đầu tiên bởi vì tôi tin rằng nó là nhanh hơn so với sử dụng chuỗi concatination hoặc sử dụng một StringBuffer để làm như vậy.

Bất kỳ ai khác có khả năng bị nhiễm khuẩn tốt hơn?

Trả lời

95

Chỉ cần sử dụng lớp StringUtils từ dự án apache commons lang. Bạn có một phương pháp leftPad:

StringUtils.leftPad("foobar", 10, '*'); // Returns "****foobar" 
+3

+1 - đó chính xác là những gì anh ấy đang tìm kiếm (hay còn gọi là 'cool'). Đối với các hành vi tương tự chính xác, nhưng đó là hiển nhiên, làm: 'StringUtils.leftPad (" ", 10, '*');' –

+3

1 giải pháp tốt đẹp, mặc dù tôi sẽ không thêm một cái lọ vào dự án của tôi chỉ cho điều đó. – abyx

+0

Cảm ơn. Có vẻ như đó là cách phù hợp hơn để sử dụng nó. May mắn thay tôi đã sử dụng cái bình này, vì vậy tôi có thể sử dụng nó ngay lập tức. –

51

Không cần phải làm các vòng lặp, và chỉ sử dụng tiêu chuẩn lớp học thư viện Java: Mã phù hợp

protected String getStringWithLengthAndFilledWithCharacter(int length, char charToFill) { 
    if (length > 0) { 
    char[] array = new char[length]; 
    Arrays.fill(array, charToFill); 
    return new String(array); 
    } 
    return ""; 
} 

Như bạn thấy đấy, tôi cũng bổ sung đối với trường hợp length == 0.

+0

sẽ không mã trong Arrays.fill() chứa một vòng lặp ... – NomeN

+4

Có thể, nhưng 1) nó có khả năng nhanh hơn và 2) đó là mã bạn không cần phải viết. – abyx

+0

Tìm tốt. Có Arrays.fill thực hiện một vòng lặp for. Nhưng về mặt lý thuyết thì điều này là tốt hơn. –

5
public static String fillString(int count,char c) { 
    StringBuilder sb = new StringBuilder(count); 
    for(int i=0; i<count; i++) { 
     sb.append(c); 
    } 
    return sb.toString(); 
} 

Điều gì là sai?

5

Để cải thiện hiệu suất mà bạn có thể có một vết cắn được xác định trước duy nhất nếu bạn biết chiều dài tối đa như:

Chuỗi template = "################## ################## ";

Và sau đó chỉ cần thực hiện chuỗi con sau khi bạn biết độ dài.

+2

+1: Tôi chỉ đọc trên một bài viết khác mà chuỗi con tạo ra một String chỉ sử dụng cùng một char [] của chuỗi gốc. Vì vậy, nó là một O (1) hoạt động (không có vòng lặp) và nó giúp tiết kiệm bộ nhớ (nếu đó là một vấn đề thực sự) –

69

Apache Commons Lang (có thể là đủ hữu ích để được vào classpath của bất kỳ dự án không tầm thường) có StringUtils.repeat():

String filled = StringUtils.repeat("*", 10); 

dễ dàng!

+2

Đây phải là câu trả lời topvoted. Cảm ơn;) – lmo

+3

Đây là câu trả lời hay nhất. Câu trả lời hàng đầu hiện tại sử dụng bảng điều khiển trái trong một cách không trực quan để làm điều gì đó mà nó không thực sự có ý định làm, điều này làm cho việc hiểu điều gì sẽ xảy ra khó khăn hơn. Câu trả lời này tự tài liệu tốt hơn. – Benjamin

3

Ở trên là tốt. Bạn có phiền không nếu tôi hỏi bạn một câu hỏi - Điều này có gây ra rắc rối cho bạn không? Nó seams với tôi bạn đang tối ưu hóa trước khi bạn biết nếu bạn cần.

Bây giờ cho giải pháp được thiết kế kỹ hơn của tôi. Trong nhiều trường hợp (bạn không phải tất cả) bạn có thể sử dụng CharSequence thay vì một String.

public class OneCharSequence implements CharSequence { 
    private final char value; 
    private final int length; 
    public OneCharSequence(final char value, final int length) { 
    this.value = value; 
    this.length = length; 
    } 
    public char charAt(int index) { 
    if(index < length) return value; 
    throw new IndexOutOfBoundsException(); 
    } 
    public int length() { 
    return length; 
    } 
    public CharSequence subSequence(int start, int end) { 
    return new OneCharSequence(value, (end-start)); 
    } 
    public String toString() { 
    char[] array = new char[length]; 
    Arrays.fill(array, value); 
    return new String(array); 
    } 
} 
2

Một lưu ý thêm: có vẻ như tất cả những cách nào để tạo ra một String dụ mới liên quan đến việc thiết phải là bản sao của bất cứ đệm bạn đang làm việc với, có thể là một char[], một StringBuffer hoặc một StringBuilder. Từ String javadoc (và được lặp đi lặp lại trong toString phương pháp tương ứng từ các lớp khác):

Nội dung của mảng ký tự được sao chép; sửa đổi tiếp theo của mảng ký tự không ảnh hưởng đến chuỗi mới được tạo.

Vì vậy, bạn sẽ có một hoạt động sao chép bộ nhớ lớn sau khi "điền nhanh" của mảng. Giải pháp duy nhất có thể tránh được vấn đề này là vấn đề từ @mlk, nếu bạn có thể quản lý trực tiếp với việc thực hiện CharSequence được đề xuất (trường hợp này có thể là gì).

PS: Tôi sẽ đăng bài này làm nhận xét nhưng tôi chưa có đủ danh tiếng để làm điều đó.

4

sử dụng Dollar rất đơn giản:

String filled = $("=").repeat(10).toString(); // produces "==========" 
+3

Có 9 '=' trong nhận xét. –

1

Hãy thử điều này Sử dụng substring (int start, int end); phương pháp

String myLongString = "abcdefghij"; 
if (myLongString .length() >= 10) 
String shortStr = myLongString.substring(0, 5)+ "..."; 

điều này sẽ trả về abcde.

14
char[] chars = new char[10]; 
Arrays.fill(chars, '*'); 
String text = new String(chars); 
0

Hãy thử jobber này

String stringy =null; 
byte[] buffer = new byte[100000]; 
      for (int i = 0; i < buffer.length; i++) { 
      buffer[i] =0; 

     } 
      stringy =StringUtils.toAsciiString(buffer); 
27

Một số giải pháp khả thi.

Điều này tạo ra một chuỗi có thời lượng '0' được điền và thay thế rồi '0' bằng charToFill (trường cũ).

String s = String.format("%0" + length + "d", 0).replace('0', charToFill); 

Điều này tạo danh sách chứa chuỗi thời gian dài bằng charToFill và sau đó tham gia Danh sách thành chuỗi.

String s = String.join("", Collections.nCopies(length, String.valueOf(charToFill))); 

Điều này tạo ra một Stream java8 không giới hạn với Strings với charToFill, hạn chế đầu ra theo chiều dài và thu thập các kết quả với một String joiner (trường mới).

String s = Stream.generate(() -> String.valueOf(charToFill)).limit(length).collect(Collectors.joining()); 
4

Giải pháp sử dụng Google Guava, vì tôi thích nó để Apache Commons-Lang:

/** 
* Returns a String with exactly the given length composed entirely of 
* the given character. 
* @param length the length of the returned string 
* @param c the character to fill the String with 
*/ 
public static String stringOfLength(final int length, final char c) 
{ 
    return Strings.padEnd("", length, c); 
} 
+0

Xem câu trả lời của javacavaj cho một giải pháp ngắn gọn hơn bằng cách sử dụng ổi. – Wienczny

1

Mi giải pháp:

pw = "1321"; 
    if (pw.length() < 16){ 
     for(int x = pw.length() ; x < 16 ; x++){ 
     pw += "*"; 
     } 
    } 

Sản lượng:

1321************ 
0

Bạn có thể sử dụng một vòng lặp while như thế này:

String text = "Hello"; 
while (text.length() < 10) { text += "*"; } 
System.out.println(text); 

sẽ cung cấp cho bạn:

Hello***** 

Hoặc có được kết quả tương tự với một phương pháp tùy chỉnh:

public static String extendString(String text, String symbol, Integer len) { 
     while (text.length() < len) { text += symbol; } 
     return text; 
    } 

Sau đó, chỉ cần gọi:

extendString("Hello", "*", 10) 

Cũng có thể là một ý tưởng hay để đặt kiểm tra độ dài để ngăn vòng lặp vô hạn.

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