Java'daki iki nesneyi olası null değerlerle karşılaştırın


Yanıtlar:


173

Java dahili kodunun kullandığı compareyöntem (diğer yöntemlerde):

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}

3
Neden yalnızca String türlerini Nesneler olarak değiştirmiyorsunuz? Ve sonra Java 7'ye geçerseniz alacağınız şeyle aynıdır
Tom

3
Hangi java sınıfı sağladığınız yöntemi içeriyor?
Volodymyr Levytskyi

30
Hey! true / false döndüren bir karşılaştırma yönteminiz olmamalıdır. Eşittir karşılaştır ile aynı değildir. Karşılaştırma sıralama için yararlı olmalıdır. Sen dönmelidir <0, ==0ya >0bir diğerinden daha düşük / rende hangi belirtmek için
Coya

10
Objects.equals(Object, Object)Mark Rotteveel cevabında işaret ettiği gibi kullanmanızı öneririm (lütfen oylayın)
Neuron

1
@Eric gerçekten iyi bir cevap vermez. En iyi yanıtın her zaman var olan her java sürümü ile uyumlu olan tek kod içeren bir kod olduğunu iddia etmeyeceğinizden eminim
Neuron

317

Java 7'den beri java.util.Objects.equals(Object, Object), iki nesneyi önemsemeden eşit kontroller yapmak için statik yöntemi kullanabilirsiniz null.

Her iki nesne de nullgeri dönerse true, biri nulldiğeri değilse geri döner false. Aksi takdirde equals, ilk nesneyi ikincisi argüman olarak çağırmanın sonucunu döndürür.


bu yaklaşım programın çalışma zamanına kadar tür denetimini tanımlar. iki sonuç: çalışma zamanında daha yavaş olacak ve IDE yanlışlıkla farklı türleri karşılaştırmaya çalıştığınızda sizi bilgilendirmeyecektir.
averasko

10
@averasko Kullandığınız zaman Object.equals(Object)derleme zamanı türü kontrolü yoktur. Objects.equals(Object, Object)Çok normal gibi çalışır equalsve yeniden çıkarsama / IDE tarafından çekler, bu kurallar da desteklenmektedir sezgisel olan Objects.equals(Object, Object)(örneğin IntelliJ IDEA 2016,2 Normal eşittir ve Nesneler'den biri ikisi için de aynı çek vardır).
Mark Rotteveel

2
Bu yaklaşımı seviyorum. Bu günlerde bazı ApacheCommons kütüphanelerini eklemenize gerek yok.
Torsten Ojaperv

1
@SimonBaars Bu bir null nesnede bir işlev çalıştırmıyor, null olabilen iki bağımsız değişken veya bir nesneye başvuru ilettiğiniz statik bir yöntemdir.
Mark Rotteveel

8
imho bu kabul edilen cevap olmalı. Yazdığım her uygulamada tekerleği yeniden keşfetmek istemiyorum
Neuron

45

Bu durumlarda Apache Commons StringUtils # eşitlerini kullanmak daha iyi olur , zaten boş dizeleri işler. Kod örneği:

public boolean compare(String s1, String s2) {
    return StringUtils.equals(s1, s2);
}

Eğer kütüphane eklemek istemiyorsanız, sadece kopya kaynak kodunu ait StringUtils#equalsyönteme ve ihtiyacınız olduğunda uygulayın.


29

Android'de API 19'un Objects.equals (str1, str2) kullanamayanlar için şunlar var:

android.text.TextUtils.equals(str1, str2);

Null güvenlidir. Nadiren daha pahalı string.equals () yöntemini kullanmak zorundadır, çünkü Android'deki özdeş dizeler Android'in String Pooling'i sayesinde neredeyse her zaman "==" işleneni ile doğru karşılaştırır ve uzunluk kontrolleri çoğu uyumsuzluğu filtrelemek için hızlı bir yoldur.

Kaynak kodu:

/**
 * Returns true if a and b are equal, including if they are both null.
 * <p><i>Note: In platform versions 1.1 and earlier, this method only worked  well if
 * both the arguments were instances of String.</i></p>
 * @param a first CharSequence to check
 * @param b second CharSequence to check
 * @return true if a and b are equal
 */
public static boolean equals(CharSequence a, CharSequence b) {
    if (a == b) return true;
    int length;
    if (a != null && b != null && (length = a.length()) == b.length()) {
        if (a instanceof String && b instanceof String) {
            return a.equals(b);
        } else {
            for (int i = 0; i < length; i++) {
                if (a.charAt(i) != b.charAt(i)) return false;
            }
            return true;
        }
    }
    return false;
}

7

3.5 sürümünden beri Apache Commons StringUtils aşağıdaki yöntemlere sahiptir:

static int  compare(String str1, String str2)
static int  compare(String str1, String str2, boolean nullIsLess)
static int  compareIgnoreCase(String str1, String str2)
static int  compareIgnoreCase(String str1, String str2, boolean nullIsLess)

Bunlar null güvenli String karşılaştırması sağlar.


6

Java 8'i kullanma :

private static Comparator<String> nullSafeStringComparator = Comparator
        .nullsFirst(String::compareToIgnoreCase); 

private static Comparator<Metadata> metadataComparator = Comparator
        .comparing(Metadata::getName, nullSafeStringComparator)
        .thenComparing(Metadata::getValue, nullSafeStringComparator);

public int compareTo(Metadata that) {
    return metadataComparator.compare(this, that);
}

4

Apache Commons StringUtils sınıfının equals (-, -) ve equalsIgnoreCase (-, -) yöntemini kullanarak iki dizeyi karşılaştırın.

StringUtils.equals (-, -) :

StringUtils.equals(null, null)   = true
StringUtils.equals(null, "abc")  = false
StringUtils.equals("abc", null)  = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false

StringUtils.equalsIgnoreCase (-, -) :

StringUtils.equalsIgnoreCase(null, null)   = true
StringUtils.equalsIgnoreCase(null, "abc")  = false
StringUtils.equalsIgnoreCase("xyz", null)  = false
StringUtils.equalsIgnoreCase("xyz", "xyz") = true
StringUtils.equalsIgnoreCase("xyz", "XYZ") = true

3

java.util.ObjectsAşağıdaki gibi kullanabilirsiniz .

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}

2
boolean compare(String str1, String str2) {
    if(str1==null || str2==null) {
        //return false; if you assume null not equal to null
        return str1==str2;
    }
    return str1.equals(str2);
}

istediğin bu mu?


5
falseHer iki Dizge de nullistenen sonuç olmayabilirse bu durum geri döner .
JScoobyCed

1
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}

1
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}

0

Tamam, "mümkün olan en iyi çözüm" ne anlama geliyor?

En okunaklıysanız, olası tüm çözümler deneyimli bir Java programcısı için hemen hemen eşdeğerdir. Ama IMO en okunabilir olanı

 public boolean compareStringsOrNulls(String str1, String str2) {
     // Implement it how you like
 }

Başka bir deyişle, uygulamayı (ideal olarak) satır içine alınabilecek basit bir yöntemle gizleyin.

(Ayrıca, kod tabanınızda zaten kullanıyorsanız, bir 3. taraf yardımcı program kitaplığına "dışarıda kaynak" da kullanabilirsiniz.)


En yüksek performanstan bahsediyorsanız, o zaman:

  1. en performanslı çözüm platforma ve bağlama bağlıdır,
  2. "bağlam" sorunlarından biri, nullargümanların göreli (dinamik) oluşma sıklığıdır ,
  3. o muhtemelen fark genel uygulama performansına bir fark yaratmak için muhtemelen çok küçük olduğundan ... hızlıdır hangi sürümün önemi ve olmaz
  4. önemliyse, PLATFORMUNUZDA en hızlı olanı bulmanın tek yolu her iki sürümü de denemek ve farkı ölçmektir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.