Tôi có nên sử dụng string.isEmpty () hoặc.


171

Tiêu đề về cơ bản nói lên tất cả. Tôi thường thử nghiệm điều này cùng với a string == null, vì vậy tôi không thực sự lo lắng về thử nghiệm không an toàn. Tôi nên sử dụng cái nào?

String s = /* whatever */;
...
if (s == null || "".equals(s))
{
    // handle some edge case here
}

hoặc là

if (s == null || s.isEmpty())
{
    // handle some edge case here
}

Trên lưu ý đó - isEmpty()thậm chí có làm gì khác hơn return this.equals("");hay return this.length() == 0;không?


26
Hãy nhớ rằng đó chỉ isEmpty()là Java 6+.
ColinD

1
Bạn có thể tạo một phương thức trợ giúp Util.String.hasValue (Chuỗi s) để kiểm tra null, trống rỗng và khoảng trắng để xử lý tất cả các trường hợp.
Cloudanger

5
@ColinD Có lẽ không có vấn đề gì - J2SE 5.0 đã hoàn thành Thời hạn kết thúc dịch vụ một thời gian trước đây.
Tom Hawtin - tackline

1
Một điều khác cần xem xét là "" .equals () lấy Object làm đối số, do đó bạn sẽ không gặp lỗi trình biên dịch nếu loại đối số thay đổi từ String sang thứ khác, tốt hơn hoặc xấu hơn.
Paul Jackson

Câu trả lời:


251

Lợi ích chính của việc "".equals(s)bạn không cần kiểm tra null ( equalssẽ kiểm tra đối số của nó và trả về falsenếu nó không), điều mà bạn dường như không quan tâm. Nếu bạn không lo lắng về sviệc null (hoặc đang kiểm tra nó), tôi chắc chắn sẽ sử dụng s.isEmpty(); nó hiển thị chính xác những gì bạn đang kiểm tra, bạn quan tâm xem có strống hay không , không phải nó có bằng chuỗi trống không


29
Cám ơn vì đã giải thích. Bây giờ tôi biết tại sao nên ưu tiên "" .equals (str) hơn str.equals ("")! Tôi đã luôn tự hỏi tại sao những người khác sử dụng điều này thường xuyên như vậy, nhưng không tính đến các giá trị null. Tuyệt vời :-)
Peter Wippermann

10
IMHO kiểm tra null vẫn cần thiết trong các ví dụ trên vì chúng tôi giả sử rằng điều kiện này phải đúng với giá trị null. s == null | | "" .equals (s)
mkorpela

5
@ Master.Aurora không, nếu được getValue()trả về null, bạn sẽ nhận được toString()
NullPulumException

12
@RenniePet Không giống như có bất kỳ phép thuật nào liên quan. Nếu slà null, bạn không thể gọi các phương thức trên nó - nó là null. ""sẽ không bao giờ là null, vì vậy bạn có thể gọi các phương thức trên nó một cách an toàn và equals()có thể xử lý trường hợp đối số của nó là null
Michael Mrozek

5
Một lưu ý về hiệu suất: isEmpty()kiểm tra độ dài bên trong của một mảng riêng trong khi equals(Object anObject)thực hiện nhiều hơn nữa (ví dụ: kiểm tra instanceof). Thông thái, isEmpty()nói chung là nhanh hơn.
Turing85

82

String.equals("")thực sự là chậm hơn một chút so với chỉ một isEmpty()cuộc gọi. Chuỗi lưu trữ một biến đếm được khởi tạo trong hàm tạo, vì Chuỗi là bất biến.

isEmpty() so sánh biến đếm với 0, trong khi bằng sẽ kiểm tra loại, độ dài chuỗi và sau đó lặp qua chuỗi để so sánh nếu kích thước khớp.

Vì vậy, để trả lời câu hỏi của bạn, isEmpty()thực sự sẽ làm ít hơn rất nhiều! và đó là một điều tốt.


3
Tôi nghĩ trong trường hợp này sự khác biệt không áp dụng; Sẽ không bao giờ có sự lặp lại qua các chuỗi để so sánh, bởi vì kích thước sẽ không khớp (trừ khi chuỗi thực sự trống, và sau đó không có ký tự nào lặp lại)
Michael Mrozek

2
Đúng nhưng bằng với bạn phải chịu một kiểm tra tham chiếu trước để xem liệu chúng có phải là cùng một đối tượng không, sau đó là một thể hiện, sau đó chuyển thành Chuỗi, kiểm tra độ dài và cuối cùng là lặp lại. Nếu cả hai Chuỗi đều trống thì đó chỉ là một kiểm tra tham chiếu đơn giản.
David Young


1
@David liên kết chết; đây là một docjar.com/html/api/java/lang/String.java.html#1011
Matt Ball

17

Một điều bạn có thể muốn xem xét bên cạnh các vấn đề khác được đề cập là isEmpty()đã được giới thiệu trong 1.6, vì vậy nếu bạn sử dụng nó, bạn sẽ không thể chạy mã trên Java 1.5 trở xuống.


4
Đó chắc chắn không phải là một mối quan tâm đối với tôi.
Matt Ball

1
Ngoài ra, câu trả lời này là 6 năm trước. Tôi hy vọng không ai phải sử dụng bất cứ thứ gì cổ xưa như Java 1.5 nữa.
Misha Nasledov

1
Thực tế có nhiều thứ có thể bị hỏng khi nâng cấp phiên bản java. Nó ít quan trọng hơn đối với một ứng dụng back-end chạy trên một máy chủ lớn, nhưng nó lại quan trọng đối với các ứng dụng khách. Các thư viện đồ họa và chiến lược thu gom rác thường bị ảnh hưởng bởi các nâng cấp java lớn và nhỏ. Trên hết, phần mềm máy khách có thể chạy trên nhiều hệ điều hành khác nhau và đôi khi có bộ nhớ hạn chế, điều đó có nghĩa là bạn thường không có ngân sách / tài nguyên để kiểm tra mọi thứ. - Có, tôi có những khách hàng vẫn gắn bó với Java 5 vào năm 2017.
bvdb

15

Bạn có thể sử dụng apache commons StringUtils isEmpty () hoặc isNotEmpty ().


1
@ 2019 và chúng tôi vẫn cần một thư viện bên thứ 3 cho việc này: thở dài:
Adam

2

Nó không thực sự quan trọng. "".equals(str)rõ ràng hơn theo ý kiến ​​của tôi.

isEmpty()trả lại count == 0;


47
Tôi muốn nói str.isEmpty()là rõ ràng hơn nhiều "".equals(str). Nó đọc như những gì bạn đang kiểm tra. Vấn đề về ý kiến ​​mặc dù, tôi đoán.
ColinD

7
Tôi nghĩ rằng một số người thích làm "" .equals (str) để tránh NPE. Cá nhân tôi không thích nó vì tôi muốn kiểm tra chuỗi không phải là null trước tiên.
CoolBeans

2

Tôi đã viết một lớp thử nghiệm có thể kiểm tra hiệu suất:

public class Tester
{
    public static void main(String[] args)
    {
        String text = "";

        int loopCount = 10000000;
        long startTime, endTime, duration1, duration2;

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.equals("");
        }
        endTime = System.nanoTime();
        duration1 = endTime - startTime;
        System.out.println(".equals(\"\") duration " +": \t" + duration1);

        startTime = System.nanoTime();
        for (int i = 0; i < loopCount; i++) {
            text.isEmpty();
        }
        endTime = System.nanoTime();
        duration2 = endTime - startTime;
        System.out.println(".isEmpty() duration "+": \t\t" + duration2);

        System.out.println("isEmpty() to equals(\"\") ratio: " + ((float)duration2 / (float)duration1));
    }
}

Tôi thấy rằng việc sử dụng .isEmpty () mất khoảng một nửa thời gian của .equals ("").


Đây không phải là một microbenchmark hợp lệ. Tôi thực sự khuyên bạn nên sử dụng Caliper hoặc công cụ đo điểm chuẩn được xây dựng có mục đích tương tự. stackoverflow.com/q/504103/139010
Matt Ball

Cảm ơn vì tiền hỗ trợ! Khi tôi có thời gian rảnh, tôi sẽ thử nghiệm một số điểm chuẩn vi mô và cập nhật câu trả lời của mình.
conapart3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.