แทนที่อักขระที่ดัชนีเฉพาะในสตริงหรือไม่


382

ฉันพยายามแทนที่ตัวละครที่ดัชนีเฉพาะในสตริง

สิ่งที่ฉันทำคือ:

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

สิ่งนี้ทำให้เกิดข้อผิดพลาด มีวิธีการทำเช่นนี้?


12
ฉันรู้ว่าสิ่งนี้ได้รับคำตอบถึงความตาย แต่มันก็คุ้มที่จะสังเกตว่ามันไม่เคยได้รับอนุญาตให้กำหนดผลลัพธ์ของการเรียกใช้ฟังก์ชันใน java ไม่มีสิ่งต่าง ๆ เช่นการอ้างอิงของ C (?) และ C ++
ApproachingDarknessFish

1
@ValekHalfHeart ใน VB คุณใช้วงเล็บเพื่อเข้าถึงดัชนีของอาเรย์นั่นอาจเป็นสาเหตุที่ทำให้ฉันสับสนเมื่อฉันเริ่มต้นใน Java: D
dpp

@ApproachingDarknessFish ฉันไม่แน่ใจว่าสิ่งที่คุณหมายถึงมันคือ "ไม่เคยได้รับอนุญาตให้กำหนดผลลัพธ์ของการเรียกใช้ฟังก์ชันใน java" แน่นอนคุณสามารถทำdouble r = Math.sin(3.14)อะไร มันเกี่ยวข้องกับคำถามนี้อย่างไร ขอบคุณ
flow2k

1
@ flow2k โอ้ jeez แสดงความคิดเห็นเก่าดังนั้นผมจึงไม่สามารถแก้ไข แต่ที่พิมพ์ผิดก็ควรจะพูดว่า "มันไม่เคยได้รับอนุญาตให้กำหนดที่จะเป็นผลมาจากการเรียกใช้ฟังก์ชันในชวา" คือคุณสามารถเขียน "foo = bar ();" แต่ไม่เคย "bar () = foo;"
ApproachingDarknessFish

ขอบคุณสำหรับการชี้แจง @ApproachingDarknessFish ฉันคิดว่ามันแปลกที่จะกำหนดบางสิ่งให้กับผลลัพธ์ของฟังก์ชั่น - มีภาษาที่อนุญาตให้ใช้จริงหรือไม่? ฉันสงสัยว่ากรณีการใช้จะเป็นอย่างไร
flow2k

คำตอบ:


566

สตริงจะไม่เปลี่ยนรูปแบบใน Java คุณไม่สามารถเปลี่ยนได้

คุณต้องสร้างสตริงใหม่โดยแทนที่อักขระ

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

หรือคุณสามารถใช้ StringBuilder:

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

System.out.println(myName);

3
อาคุณหมายถึงชอบreplaceวิธีที่จะไม่แก้ไขสตริง แต่เพิ่งจะส่งกลับสตริงใหม่หรือไม่
dpp

1
มันค่อนข้างซับซ้อน Mr.Petar นั่นเป็นวิธีที่ดีที่สุดที่คุณจะทำหรือไม่? อ่าฉันเคยได้ยิน StringBuilder มาก่อนมันสร้างความแตกต่างได้ไหม? มันจะทำให้ฉันมีวิธีที่ง่ายขึ้นไหม?
dpp

158

เปลี่ยนสตริงให้เป็นอักขระถ่าน [] แทนที่ตัวอักษรตามดัชนีจากนั้นแปลงอาร์เรย์กลับเป็นสตริง

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

1
รักทางออกนี้ ฉันสิ้นสุดการเปลี่ยนบรรทัดที่ 3 เป็น myNameChars [index] = character.toCharArray () [0]; สำหรับการทำให้เข้าใจง่าย ทางออกที่ดี
Dale

2
มันดูดีกว่ารุ่นก่อนอื่นmyName.substring(0,4)+'x'+myName.substring(5);
user924

มันง่ายกว่ามาก
Shiva Acharjee

19

Stringเป็นคลาสที่ไม่เปลี่ยนรูปแบบใน java วิธีการใด ๆ ที่ดูเหมือนว่าจะแก้ไขมันจะส่งกลับวัตถุสตริงใหม่ที่มีการปรับเปลี่ยนเสมอ

หากคุณต้องการจัดการสตริงให้พิจารณาStringBuilderหรือStringBufferในกรณีที่คุณต้องการความปลอดภัยของเธรด


12

ฉันเห็นด้วยกับ Petar Ivanov แต่มันจะดีที่สุดถ้าเราใช้วิธีต่อไปนี้:

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
และอะไรทำให้โซลูชันของคุณดีขึ้น?
dpp

6

ขณะที่ก่อนหน้านี้ตอบที่นี่Stringอินสแตนซ์ที่ไม่เปลี่ยนรูป StringBufferและStringBuilderไม่แน่นอนและเหมาะสมกับวัตถุประสงค์ดังกล่าวไม่ว่าคุณจะต้องปลอดภัยหรือไม่

อย่างไรก็ตามมีวิธีการแก้ไขสตริง แต่ฉันจะไม่แนะนำเพราะมันไม่ปลอดภัยไม่น่าเชื่อถือและสามารถถือได้ว่าเป็นการโกง: คุณสามารถใช้การสะท้อนเพื่อปรับเปลี่ยนcharอาร์เรย์ภายในที่วัตถุสตริงมี การสะท้อนกลับช่วยให้คุณสามารถเข้าถึงเขตข้อมูลและวิธีการที่ปกติถูกซ่อนอยู่ในขอบเขตปัจจุบัน (วิธีส่วนตัวหรือเขตข้อมูลจากคลาสอื่น ... )

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

คุณสามารถเขียนทับสตริงได้ดังนี้:

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

โปรดสังเกตว่าสายอักขระmyNameเกิดขึ้นบนทั้งสองบรรทัดและบนทั้งสองด้านของบรรทัดที่สอง

ดังนั้นแม้ว่าในทางเทคนิคสตริงอาจไม่เปลี่ยนรูป แต่ในทางปฏิบัติคุณสามารถปฏิบัติต่อมันได้โดยการเขียนทับมัน


ฉันไม่ได้ลบคำตอบของคุณ แต่ฉันต้องยอมรับว่าฉันมีปัญหากับคำว่า "เขียนทับ" (แม้ว่าฉันคิดว่าเราเห็นด้วยกับแนวคิดที่อยู่เบื้องหลัง) วัตถุนั้นยังคงไม่เปลี่ยนแปลง คุณเพิ่งสร้างตัวแปรอ้างอิงวัตถุอื่น คุณน่าสนใจที่จะพูดถึงว่าคุณสร้างอินสแตนซ์ String อย่างน้อยสี่ตัวในตัวอย่างของคุณ
C.Champagne

0

สิ่งแรกที่ฉันควรสังเกตุคือcharAtวิธีการและการกำหนดค่าโดยใช้เครื่องหมายเท่ากับจะไม่ทำอะไรเลย หากสตริงไม่เปลี่ยนรูปcharAtวิธีการในการเปลี่ยนแปลงวัตถุสตริงจะต้องได้รับการโต้แย้งที่มีตัวละครใหม่ น่าเสียดายที่สตริงไม่เปลี่ยนรูป ในการปรับเปลี่ยนสตริงฉันต้องใช้ StringBuilder ตามที่นาย Petar Ivanov แนะนำ


-7

สิ่งนี้จะได้ผล

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

ผลลัพธ์: domaxokz


1
แม้ว่าฉันจะเกลียดวิธีการนี้ที่ได้รับอนุญาต "แก้ไขได้" ของงานของผู้อื่นในไซต์ StackOverFlow นี้ ไม่ยุติธรรมอย่างทั่วถึง: /
Diabolus Infernalis

2
ข้อผิดพลาดทางไวยากรณ์ และแม้ว่าจะได้รับการแก้ไขบอกว่าฉันต้องการแทนที่ 'o' ตัวแรกด้วย 'x' ตัวที่สองก็จะถูกแทนที่ด้วยเช่นกัน
dpp

2
สิ่งนี้จะแทนที่ตัวละครทั้งหมดซึ่งเหมือนกับ charAt 4
Shripad Bhat

1
ปัญหา: myName.replace(myName.charAt(5),'x')จะให้คุณdxmanxkzซึ่งอาจไม่จำเป็นต้องใช้
Dawood ibn Kareem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.