Bagaimana cara membuat perbandingan string saya tidak peka huruf besar / kecil?

111

Saya membuat program Java untuk membandingkan dua string:

String s1 = "Hello";
String s2 = "hello";

if (s1.equals(s2)) {
    System.out.println("hai");
} else {
    System.out.println("welcome");
}

Ini menampilkan "selamat datang". Saya mengerti ini peka huruf besar / kecil. Tapi masalah saya adalah saya ingin membandingkan dua string tanpa sensitivitas huruf. Yaitu saya mengharapkan hasilnya hai.

pengguna268018
sumber
3
Jika Anda tahu ini peka huruf besar / kecil, Anda dapat mengonversi keduanya menjadi huruf kecil atau huruf besar sebelum membandingkan.
fastcodejava
jika Anda menggunakan s1.equalsIgnoreCase(s2)Anda mungkin gagal melakukannya di mana pun itu perlu dilakukan. Saya menyarankan agar Anda menemukan dari mana string itu berasal - file atau database atau mungkin input pengguna - dan ubah menjadi huruf besar (atau huruf kecil) dan terus menggunakan .equals untuk perbandingan.
H2ONaCl
2
Jangan ubah menjadi huruf kecil / besar (seperti yang disarankan oleh komentar di atas), gunakan equalsIgnoreCasependekatan yang diterima . Baca masalah Turki I dan masalah Unicode serupa untuk alasannya.
Ohad Schneider
1
@OhadSchneider equalsIgnoreCasemengembalikan nilai yang salah untuk bahasa Turki, karena mengembalikan nilai true untuk membandingkan "i" dan "I", meskipun seharusnya mengembalikan false. Jadi saya curiga jika Anda ingin mempertimbangkan lokal, Collatorsebenarnya cara yang harus dilakukan.
Trejkaz
1
@OhadSneider Aku ingin tahu. Dikatakan bahwa melakukannya per karakter menghasilkan hasil yang sama, tetapi melakukan toLowerCase/ toUpperCasepada seluruh string dan melakukannya per karakter memberikan dua hasil yang berbeda juga.
Trejkaz

Jawaban:

171
  • Yang terbaik akan menggunakan s1.equalsIgnoreCase(s2): (lihat javadoc )
  • Anda juga dapat mengubahnya menjadi huruf besar / kecil dan penggunaan s1.equals(s2)
Michael Bavin
sumber
39
Ketahuilah bahwa kedua solusi belum tentu identik untuk semua lokal. String # equalsIgnoreCase tidak menggunakan aturan kapitalisasi khusus lokal, sedangkan String # toLowerCase dan #toUpperCase menggunakannya.
jarnbjo
1
@jarnbjo Bisa kasih contoh dimana bedanya?
towi
16
Aturan kasus khusus lokal setidaknya diterapkan untuk bahasa Turki dan Jerman. Bahasa Turki memperlakukan I dengan dan tanpa titik sebagai dua huruf berbeda, membuat pasangan huruf kecil / besar iİ dan ıI sementara bahasa lain memperlakukan iI sebagai pasangan dan tidak menggunakan huruf ı dan İ. Dalam bahasa Jerman, huruf kecil ß dikapitalisasi sebagai "SS".
jarnbjo
24

String.equalsIgnoreCase adalah pilihan paling praktis untuk perbandingan string tidak peka huruf besar / kecil.

Namun, perlu diketahui bahwa metode ini tidak melakukan pelipatan atau dekomposisi kasus penuh sehingga tidak dapat melakukan pencocokan tanpa casing seperti yang ditentukan dalam standar Unicode. Faktanya, JDK API tidak menyediakan akses ke informasi tentang data karakter lipat kasus, jadi tugas ini paling baik didelegasikan ke pustaka pihak ketiga yang telah dicoba dan diuji.

Library tersebut adalah ICU , dan berikut adalah cara seseorang dapat mengimplementasikan utilitas untuk perbandingan string tidak peka huruf besar / kecil:

import com.ibm.icu.text.Normalizer2;

// ...

public static boolean equalsIgnoreCase(CharSequence s, CharSequence t) {
    Normalizer2 normalizer = Normalizer2.getNFKCCasefoldInstance();
    return normalizer.normalize(s).equals(normalizer.normalize(t));
}
    String brook = "flu\u0308ßchen";
    String BROOK = "FLÜSSCHEN";

    assert equalsIgnoreCase(brook, BROOK);

Perbandingan yang naif dengan String.equalsIgnoreCase, atau String.equalspada string dengan huruf besar atau kecil akan gagal bahkan dalam pengujian sederhana ini.

(Namun perlu diperhatikan bahwa citarasa pelipat kasing yang telah ditentukan sebelumnya getNFKCCasefoldInstancetidak tergantung pada lokasi; untuk lokal Turki, UCharacter.foldCasemungkin diperlukan lebih banyak pekerjaan yang melibatkan .)

glts
sumber
22

Anda harus menggunakan compareToIgnoreCasemetode Stringobjek.

int compareValue = str1.compareToIgnoreCase(str2);

if (compareValue == 0)itu artinya str1sama str2.

Aliti
sumber
10
import java.lang.String; //contains equalsIgnoreCase()
/*
*
*/
String s1 = "Hello";
String s2 = "hello";

if (s1.equalsIgnoreCase(s2)) {
System.out.println("hai");
} else {
System.out.println("welcome");
}

Sekarang akan menampilkan: hai

KNU
sumber
5

Di API Java default Anda memiliki:

String.CASE_INSENSITIVE_ORDER

Jadi, Anda tidak perlu menulis ulang pembanding jika akan menggunakan string dengan struktur data yang Diurutkan.

String s = "some text here";
s.equalsIgnoreCase("Some text here");

Apakah yang Anda inginkan untuk pemeriksaan kesetaraan murni dalam kode Anda sendiri.

Sekedar informasi lebih lanjut tentang apa saja yang berhubungan dengan persamaan String di Jawa. Fungsi hashCode () dari kelas java.lang.String "peka huruf besar kecil":

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

Jadi, jika Anda ingin menggunakan Hashtable / HashMap dengan Strings sebagai kunci, dan memiliki kunci seperti "SomeKey", "SOMEKEY" dan "somekey" dianggap sama, maka Anda harus membungkus string di kelas lain (Anda tidak dapat memperluas String karena ini adalah kelas terakhir). Sebagai contoh :

private static class HashWrap {
    private final String value;
    private final int hash;

    public String get() {
        return value;
    }

    private HashWrap(String value) {
        this.value = value;
        String lc = value.toLowerCase();
        this.hash = lc.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o instanceof HashWrap) {
            HashWrap that = (HashWrap) o;
            return value.equalsIgnoreCase(that.value);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return this.hash;
    }
}

dan kemudian gunakan seperti itu:

HashMap<HashWrap, Object> map = new HashMap<HashWrap, Object>();
le-doude
sumber
2

Perhatikan bahwa Anda mungkin ingin melakukan pemeriksaan null pada mereka juga sebelum melakukan .equals atau .equalsIgnoreCase.

Objek String null tidak dapat memanggil metode sama dengan.

yaitu:

public boolean areStringsSame(String str1, String str2)
{
    if (str1 == null && str2 == null)
        return true;
    if (str1 == null || str2 == null)
        return false;

    return str1.equalsIgnoreCase(str2);
}
VeenarM
sumber
1
Catatan: kedua dua pernyataan dapat dikombinasikan untuk menghasilkan hasil yang sama seperti ini: if (str1 == null || str2 == null) return false;.
LuckyMe
Kode yang dimodifikasi menjadi lebih bersih sesuai komentar di atas - hari yang panjang :)
VeenarM
1
Anda juga dapat mengubah baris pertama if (str1 == str2) return true;yang melayani null dan juga pintasan kasus di mana dua referensi string merujuk ke objek string yang sama.
Barney
1

Untuk menjadi nullsafe, Anda dapat menggunakan

org.apache.commons.lang.StringUtils.equalsIgnoreCase(String, String)

atau

org.apache.commons.lang3.StringUtils.equalsIgnoreCase(CharSequence, CharSequence)
brandstaetter
sumber
-6
public boolean newEquals(String str1, String str2)
{
    int len = str1.length();
int len1 = str2.length();
if(len==len1)
{
    for(int i=0,j=0;i<str1.length();i++,j++)
    {
        if(str1.charAt(i)!=str2.charAt(j))
        return false;
    }`enter code here`
}
return true;
}
javacoder.dll
sumber