Bir dizgideki belirli bir dizindeki bir karakter değiştirilsin mi?


382

Bir dize belirli bir dizindeki bir karakteri değiştirmek çalışıyorum.

Yaptığım şey:

String myName = "domanokz";
myName.charAt(4) = 'x';

Bu bir hata verir. Bunu yapmak için herhangi bir yöntem var mı?


12
Bunun ölümle sonuçlandığını fark ettim, ama java'da bir işlev çağrısının sonucunu asla atamasına izin verilmediğini belirtmek gerekir . C (?) Ve C ++ referansları diye bir şey yoktur.
ApproachingDarknessFish

1
VB'de @ValekHalfHeart, bir dizinin dizinine erişmek için parantez kullanıyorsunuz, Java'da başlarken neden kafam karışıyor olabilir: D
dpp

@ApproachingDarknessFish "Java'da bir işlev çağrısının sonucunu asla atamasına izin verilmez" derken ne demek istediğinizden emin değilim. Elbette yapabilirsin double r = Math.sin(3.14)? Bu soru ile nasıl bir ilişkisi var? Teşekkürler.
flow2k

1
@ flow2k Oh Tanrım, eski comment Ben düzenleme yapamam ama bir yazım hatası olduğunu, bu "o atamak için asla izin söylemek böylece için Java bir işlev çağrısının sonucu". Yani "foo = bar ();" yazabilirsiniz. ama asla "bar () = foo;".
ApproachingDarknessFish

@ApproachingDarknessFish açıklaması için teşekkürler. Bence bir işlevin sonucuna bir şey atamak garip olurdu - buna izin veren diller var mı? Kullanım durumunun ne olacağını merak ediyorum.
flow2k

Yanıtlar:


566

Dize Java ile değiştirilemez. Onları değiştiremezsiniz.

Karakter değiştirilerek yeni bir dize oluşturmanız gerekir.

String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);

Veya bir StringBuilder kullanabilirsiniz:

StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');

System.out.println(myName);

3
Ah, replacedizeyi değiştirmeyecek ama yeni bir dizge döndürecek yöntem gibi mi demek istediniz ?
dpp

1
Bu biraz karmaşık Mr.Petar. Bunu yapmanın en iyi yolu bu mu? Ah, daha önce StringBuilder'ı duydum, bu bir fark yaratıyor mu? Bana daha kolay bir yöntem sağlayacak mı?
dpp

158

Dizeyi bir char [] biçimine dönüştürün, harfi dizine göre değiştirin, sonra diziyi tekrar Dizeye dönüştürün.

String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);

1
Bu çözümü seviyorum. 3. satır myNameChars [index] = character.toCharArray () [0] olacak şekilde değiştirdi; basitleştirme için. Güzel çözüm.
Dale

2
diğer çirkin olandan çok daha iyi görünüyormyName.substring(0,4)+'x'+myName.substring(5);
user924

Çok daha basit
Shiva Acharjee

19

StringJava'da değişmez bir sınıftır. Bunu değiştiren herhangi bir yöntem her zaman değiştirilmiş yeni bir dize nesnesi döndürür.

Bir dizgeyi değiştirmek istiyorsanız, iplik güvenliğine ihtiyaç duyduğunuzda StringBuilderveya düşünmeniz StringBufferdurumunda.


12

Petar Ivanov ile aynı fikirdeyim ancak en iyi şekilde şu şekilde uygularsak:

public String replace(String str, int index, char replace){     
    if(str==null){
        return str;
    }else if(index<0 || index>=str.length()){
        return str;
    }
    char[] chars = str.toCharArray();
    chars[index] = replace;
    return String.valueOf(chars);       
}

21
ve çözümünüzü daha iyi hale getiren nedir?
dpp 03

6

Burada daha önce yanıtlandığı gibi, Stringörnekler değişmez . StringBufferve StringBuildersen parçacığı güvenli olup olmayacağını gerekip gerekmediğini değişken ve böyle bir amaç için uygundur.

Ancak bir Dize değiştirmek için bir yol var ama güvensiz, güvenilmez ve hile olarak kabul edilebilir çünkü asla tavsiye etmem: String nesnesinin içerdiği iç diziyi değiştirmek için yansıma kullanabilirsiniz char. Yansıma , normalde geçerli kapsamda gizlenen alanlara ve yöntemlere erişmenizi sağlar (özel yöntemler veya başka bir sınıftan alanlar ...).

public static void main(String[] args) {
    String text = "This is a test";
    try {
        //String.value is the array of char (char[])
        //that contains the text of the String
        Field valueField = String.class.getDeclaredField("value");
        //String.value is a private variable so it must be set as accessible 
        //to read and/or to modify its value
        valueField.setAccessible(true);
        //now we get the array the String instance is actually using
        char[] value = (char[])valueField.get(text);
        //The 13rd character is the "s" of the word "Test"
        value[12]='x';
        //We display the string which should be "This is a text"
        System.out.println(text);
    } catch (NoSuchFieldException | SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

4

Aşağıdaki gibi bir dizenin üzerine yazabilirsiniz:

String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);  

Dizenin myNameher iki satırda ve ikinci satırın her iki tarafında oluştuğunu unutmayın .

Bu nedenle, dizeler teknik olarak değişmez olsa da, pratikte, üzerine yazarak bunları düzenlenebilir olarak ele alabilirsiniz.


Cevabınızı küçümsemedim ama "üzerine yazma" terimiyle ilgili bir sorunum olduğunu itiraf etmeliyim (yine de arka plandaki konsepti kabul ettiğimizi düşünüyorum). Nesnenin kendisi değişmeden kalır. Sadece değişkeninizi başka bir nesneye referans yaparsınız. Bu arada, örneğinizde en az dört String örneği oluşturduğunuzu belirtmek ilginçtir.
C.Champagne

0

Fark etmem gereken ilk şey charAt, bir yöntem ve eşittir işaretini kullanarak değer atamanın hiçbir şey yapmayacağıdır. Bir dize değişmezse, charAtdize nesnesine değişiklik yapmak için yöntem yeni karakteri içeren bir bağımsız değişken almalıdır. Ne yazık ki, dize değişmez. Dize değiştirmek için Bay Petar Ivanov tarafından önerildiği gibi StringBuilder kullanmak gerekiyordu.


-7

bu çalışacak

   String myName="domanokz";
   String p=myName.replace(myName.charAt(4),'x');
   System.out.println(p);

Çıktı: domaxokz


1
Her ne kadar i güçlü bir şekilde bu StackOverFlow sitesinde başkalarının çalışma "düzenlenebilirlik" izin verilen yöntemden nefret. iyice adaletsiz: /
Diabolus Infernalis

2
Sözdizimi hatası. Ve düzeltilse bile, ilk 'o' yerine 'x' koymak istiyorum, ikinci 'o' de değiştirilecek.
dpp

2
Bu karakter charAt 4 ile aynı olan tüm karakterlerin yerine geçecektir.
Shripad Bhat

1
Sorun: myName.replace(myName.charAt(5),'x')size vereceğiz dxmanxkz, ki bu muhtemelen gerekli değildir.
Dawood ibn Kareem
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.