2014-07-04 12 views
19

Như tôi đã hiểu, khi tôi thực hiện String baz = "foo" + "bar" + "123" trình biên dịch Java sẽ thay thế biểu thức bằng một số StringBuilder. Tuy nhiên giáo viên Java của chúng tôi nói với chúng tôi rằng đó là thực hành tốt để luôn luôn sử dụng một cách rõ ràng StringBuilder ...Khi nào bạn nên sử dụng một StringBuilder một cách rõ ràng?

Tôi thích hợp trong giả định tôi sẽ chỉ cần phải sử dụng một cách rõ ràng StringBuilder khi concatenating bên trong vòng lặp như đã nêu trong an answer to Stack Overflow question String builder vs string concatenation? Có trường hợp nào khác mà bạn nên sử dụng một cách rõ ràng StringBuilder thay vì + hoặc +=?

+5

'để luôn sử dụng StringBuilder một cách rõ ràng' - đó không phải là phương pháp hay. Bạn sẽ hy sinh khả năng đọc mã để đạt được hiệu suất 0,0000000000001%. Sử dụng StringBuilder khi bạn định nối thêm hàng nghìn chuỗi. –

+2

Tôi không chắc chắn lý do tại sao bạn giáo viên java rất quan tâm đến việc sử dụng StringBuilder. StringBuilder là tuyệt vời và tất cả nhưng giao dịch java với nó trong nội bộ. – nafas

+10

Giáo viên của bạn sai. Bạn nói đúng. –

Trả lời

35

Tổng quát hơn "vòng trong" - bất kỳ lúc nào bạn muốn ghép nối trên nhiều câu lệnh và không cần kết quả trung gian dưới dạng chuỗi. Ví dụ:

StringBuilder builder = new StringBuilder("Start"); 
if (someCondition) { 
    builder.append("Foo"); 
} 
if (someOtherCondition) { 
    builder.append("Bar"); 
} 
builder.append("End"); 
String result = builder.toString(); 

Trong khi bạn có thể viết rằng:

String result = "Start" + (someCondition ? "Foo" : "") 
    + (someOtherCondition ? "Bar" : "") + "End"; 

... mà trở nên khó đọc. Và nếu có nhiều phát biểu hơn trong các cơ quan if, nó thậm chí có thể không khả thi.

Để khắc phục điều gì đó trong câu hỏi của bạn mặc dù:

Theo tôi được biết, khi tôi làm Chuỗi baz = "foo" + "thanh" + "123" trình biên dịch java nội thay thế biểu thức với một StringBuilder .

Không, khi bạn viết rằng biểu hiện trình biên dịch nhận ra rằng đó là một thời gian biên dịch không đổi, và thay thế nó bằng

String baz = "foobar123"; 

Đó là một lý do rất tốt không để sử dụng một cách rõ ràng StringBuilder - các mã trên rõ ràng là hiệu quả hơn trong thời gian thực hiện hơn

String baz = new StringBuilder("foo").append("bar").append("123").toString(); 

Khi nó không phải là hằng số biên dịch, trình biên dịch Java sẽ thực hiện phép nối bằng cách sử dụng một số StringBuilder, thường để lại cho bạn mã dễ hiểu hơn với việc sử dụng rõ ràng StringBuilder, nhưng không có hiệu suất. Tôi nghi ngờ giáo viên của bạn hoặc không hiểu chính xác chuỗi nối, hoặc chỉ cần đọc ở một nơi khác mà bạn nên sử dụng StringBuilder mà không hiểu đầy đủ khi thích hợp.

+3

Cảm ơn bạn và mọi người khác về câu trả lời chi tiết, mọi thứ giờ đã rõ ràng hơn nhiều. là bạn Jon Skeet tác giả của thư viện dernc.c? bởi vì tôi đang sử dụng một cổng java của dự án hiện tại của tôi :) user2711115

+0

Chỉ cần vấp phải điều này - tôi không tin rằng C# sử dụng một StringBuilder bên dưới theo mặc định? Bất kỳ ý tưởng tại sao sự khác biệt giữa C# và Java - trước đây tôi đã tự hỏi tại sao C# không chỉ quan tâm đến điều này cho bạn. – Ian

+0

@Ian: C# sử dụng 'String.Concat' thay vì' StringBuilder', nhưng đó là cùng một loại nguyên tắc. –

1

Obi Wan đã nói rằng chỉ có Sith nghĩ trong tuyệt đối hoặc một cái gì đó tương tự ...

Thật tốt bạn biết rằng trình biên dịch Java trong nội bộ thay thế "+" trên Strings với việc sử dụng các StringBuilder. Đây là những gì các trình biên dịch cho: để làm cho cuộc sống dễ dàng hơn.

Trừ khi bạn có vòng lặp, như trong trường hợp được liên kết hoặc điều kiện từ ví dụ của Jon Skeet, chủ yếu là vấn đề dễ đọc và dễ bảo trì.

Thay

return "User " + userName + " said"; 

với

new StringBuilder().append("User ").append(userName).append(" said").toString(); 

làm cho mã dài hơn, có thể là khó khăn hơn để sửa đổi, có nhiều khả năng để buộc ngắt dòng và mang đến cho bạn hiệu suất hơn.

Tuy nhiên, khi bổ sung không chỉ áp dụng cho các chuỗi, mà còn có các số liên quan, có thể giải pháp với StringBuilder đôi khi có thể dễ đọc hơn.

return "User" + a + b + " said: " + (c + d); 

có thể gây nhầm lẫn hơn như:

return new StringBuilder().append("User ").append(a).append(b) 
    .append(" said: ").append(c+d).toString(); 

Nhưng nó chủ yếu là vấn đề quan điểm và phong cách mã hóa. "Nên" không phải là một từ tốt ở đây.

+0

Tôi chỉ lặp lại bản thân mình - 'return 'Người dùng" + a + b + "đã nói:" + (c + d); 'vẫn còn dễ đọc hơn nhiều so với phiên bản sau, đặc biệt nếu các số được đặt tên hợp lý - cũng lưu ý rằng bạn hiếm khi sử dụng hai số bên cạnh nhau * mà không có bất kỳ dấu phân cách nào ở giữa *; Tôi đã không nhìn thấy bất kỳ ví dụ thực tế cuộc sống mà thực sự sẽ sử dụng SB để * tăng * rõ ràng - Tôi muốn nói đó là tốt để * obfuscate * điều, mặc dù. – vaxquis

1

Chúng cũng tốt cho việc triển khai các từ như từ khóa 'ra' của C# bằng chuỗi. Ví dụ

public int getInt(StringBuilder error) 
{ 
    int retVal = 0; 

    if (someErrorOccured) 
     error.append("Couldn't get int because of..."); 
    else 
     retVal = whatItsSupposedToBe; 

    return retVal; 
} 
Các vấn đề liên quan