วิธีแปลง Char เป็น String ใน Java (ตัวอย่าง)

⚡ สรุปอย่างชาญฉลาด

การแปลงอักขระเป็นสตริงใน Java ใช้การเรียกเพียงครั้งเดียวไปยัง String.valueOf(myChar) หรือ Character.toString(myChar) การเคลื่อนที่ในทิศทางตรงกันข้ามใช้ charAt(index) ซึ่งดึงอักขระหนึ่งตัวออกจากสตริงตามตำแหน่งของมัน

  • 🔘 ค่าสตริงของ: String.valueOf(myChar) จะส่งคืนสตริงที่มีอักขระเดียว และระบุเจตนาของการแปลงได้อย่างชัดเจนที่สุด
  • ☑️ Character.toString: Character.toString(myChar) ทำงานแบบเดียวกัน และเนื่องจาก Java 9. จะส่งต่อการทำงานไปยัง String.valueOf โดยตรง
  • charAt: charAt(index) จะส่งคืนอักขระที่ตำแหน่งเริ่มต้นที่ศูนย์ และจะโยนข้อยกเว้น StringIndexOutOfBoundsException หากอยู่นอกช่วงที่ถูกต้อง
  • 🧪 อาร์เรย์อักขระ: toCharArray() จะแยกสตริงออกเป็นอาร์เรย์ของอักขระ และ new String(chars) จะสร้างข้อความขึ้นใหม่จากอาร์เรย์นั้น
  • 🛠️ ไม่มีการคัดเลือกนักแสดง: ไม่สามารถแปลงค่า String เป็น char ได้ เนื่องจาก String เป็นอ็อบเจ็กต์ ไม่ใช่ชนิดข้อมูลพื้นฐานที่เกี่ยวข้อง
  • 📌 ข้อจำกัดของ Unicode: อักขระหนึ่งตัว (char) เก็บหน่วยรหัส UTF-16 ขนาด 16 บิตหนึ่งหน่วย ดังนั้นอีโมจิหนึ่งตัวจึงต้องการอักขระสองตัว หรือ Character.toString(codePoint)

Java โค้ดแปลงอักขระเป็นสตริง และแปลงสตริงกลับเป็นอักขระอีกครั้ง

ในบทเรียนนี้ เราจะศึกษาโปรแกรมสั้น ๆ สองโปรแกรมที่ใช้ในการย้ายค่าระหว่างสองวิธี Java ข้อความในร้านค้า:

  1. แปลงอักขระเป็นสตริง
  2. แปลงสตริงเป็นอักขระ

ทั้งสองประเภทไม่สามารถใช้แทนกันได้ char คือชนิดข้อมูลพื้นฐานที่เก็บหน่วยรหัส UTF-16 ขนาด 16 บิตเพียงหนึ่งหน่วย เขียนด้วยเครื่องหมายอัญประกาศเดี่ยวเป็น 'g' ส่วน string คืออ็อบเจ็กต์ที่เก็บลำดับของหน่วยรหัสเหล่านั้น เขียนด้วยเครื่องหมายอัญประกาศคู่เป็น “Guru99” เนื่องจากอย่างหนึ่งเป็นประเภทพื้นฐานและอีกอย่างหนึ่งเป็นประเภทวัตถุ จึงไม่มีการแปลงประเภทใดที่สามารถเชื่อมโยงทั้งสองเข้าด้วยกันได้ ต้องใช้วิธีการจากไลบรารีในการทำงาน และ Java จัดเตรียมไว้หนึ่งชิ้นสำหรับแต่ละทิศทาง

แปลงถ่านเป็นสตริง

มีหลายวิธีในการแปลงอักขระเป็นสตริง Javaภายใน a Java สตริงจะเก็บข้อความของมัน โดยพื้นฐานแล้วมันคืออาร์เรย์ของหน่วยรหัส ซึ่งเป็นเหตุผลว่าทำไมตัวอักษรหนึ่งตัวจึงสามารถแทรกเข้าไปในอาร์เรย์นั้นได้อย่างง่ายดาย ตัวอักษร (char) เป็นชนิดข้อมูลแบบไม่มีเครื่องหมายขนาด 16 บิต มีความกว้างสองไบต์ และเก็บค่าได้ตั้งแต่ 0 ถึง 65,535

เราสามารถแปลงอักขระ (char) เป็นสตริง (String) ได้โดยใช้ 2 วิธี คือ เมธอด static toString() ของคลาส Character และเมธอด static valueOf() ของคลาส String ทั้งสองเมธอดจะคืนค่าเป็นสตริงใหม่ที่มีความยาวหนึ่งอักขระ และโปรแกรมสองโปรแกรมด้านล่างจะแสดงผลลัพธ์เดียวกัน

วิธีที่ 1: การใช้วิธี toString()

โปรแกรมด้านล่างนี้จะเก็บตัวอักษร g ไว้ในตัวแปร a ตัวแปรถ่าน จากนั้นส่งค่าไปยัง Character.toString() ซึ่งจะคืนค่าตัวอักษรนั้นออกมาเป็นสตริง โค้ดสามารถแก้ไขได้ ดังนั้นลองเปลี่ยนตัวอักษรแล้วรันอีกครั้งเพื่อดูผลลัพธ์

public class CharToString_toString {
  public static void main(String[] args) {
    //input character variable 
    char myChar = 'g';
    //Using toString() method
    //toString method take character parameter and convert string.
    String myStr = Character.toString(myChar);
    //print string value
    System.out.println("String is: " + myStr);
  }
} 

ผลลัพธ์ที่คาดหวัง :

String is: g

วิธีที่ 2: การใช้เมธอด valueOf()

โปรแกรมที่สองจะแทนที่ด้วย String.valueOf(myChar) และไม่เปลี่ยนแปลงสิ่งอื่นใด เนื่องจาก Java 9. การเรียกทั้งสองแบบเป็นการดำเนินการเดียวกัน: Character.toString(char) ถูกนำไปใช้ในรูปแบบของการเรียก String.valueOf(char) ดังนั้นจึงไม่มีวิธีใดเร็วกว่าอีกวิธีหนึ่งอย่างเห็นได้ชัด

public class CharToString_valueOf {
  public static void main(String[] args) {
    char myChar = 'g';
    //valueOf method take character parameter and convert string.
    String myStr = String.valueOf(myChar);
    ////print string value
    System.out.println("String is: " + myStr);
  }
}

ผลลัพธ์ที่คาดหวัง :

String is: g

วิธีอื่นๆ ในการแปลงอักขระเป็นสตริง

ในโค้ดเก่าและคำถามสัมภาษณ์งาน พบว่ามีอีกสี่วิธีที่ใช้ได้ แต่ไม่มีวิธีใดที่อ่านง่ายเหมือนสองวิธีข้างต้น และสองวิธีในจำนวนนั้นมีการจัดสรรทรัพยากรเกินความจำเป็น

public class CharToStringMore {
  public static void main(String[] args) {
    char myChar = 'g';

    // 1. concatenation with an empty literal
    String byConcat = myChar + "";

    // 2. the Character wrapper instance method
    String byWrapper = Character.valueOf(myChar).toString();

    // 3. a one-element array of code units
    String byArray = new String(new char[]{myChar});

    // 4. the format() helper with the %c conversion
    String byFormat = String.format("%c", myChar);

    System.out.println(byConcat + byWrapper + byArray + byFormat);
  }
}

ผลลัพธ์ที่คาดหวัง:

gggg

ตารางนี้แสดงให้เห็นว่าแต่ละเส้นทางนั้นคุ้มค่าแก่การใช้งานเมื่อใด

วิธี ตัวอย่าง หมายเหตุ :
สตริง.ค่าของ(char) ค่าสตริงของ (myChar) แนะนำครับ เรียกใช้งานเพียงครั้งเดียว ไม่มีการเพิ่มอ็อบเจ็กต์ใดๆ นอกเหนือจากสตริงที่ส่งกลับมา
Character.toString(char) Character.toString(myChar) ดีพอๆ กัน มีจำหน่ายตั้งแต่ Java 1.4 และส่งต่อไปยัง String.valueOf เนื่องจาก Java 9.
เรียงต่อกัน มายชาร์ + “” ผลงาน และบน Java ในเวอร์ชัน 9 และเวอร์ชันต่อมา มันจะคอมไพล์เป็นการเรียกใช้ invokedynamic แทนที่จะเป็น StringBuilder ดังนั้นคำเตือนเก่าที่ว่ามันช้าจึงไม่เป็นความจริงอีกต่อไป แต่มันก็ยังคงซ่อนเจตนาเอาไว้
ตัวห่ออักขระ Character.valueOf(myChar).toString() Boxใช้ Character.valueOf แทนคอนสตรัคเตอร์ Character(char) ใหม่ ซึ่งถูกยกเลิกและเตรียมลบออกแล้ว Java 9.
อาร์เรย์อักขระ สตริงใหม่ (อักขระใหม่[]{myChar}) จัดสรรอาร์เรย์และคัดลอกอาร์เรย์นั้น สงวนไว้สำหรับกรณีที่คุณมีอาร์เรย์อักขระอยู่แล้ว
รูปแบบสตริง String.format(“%c”, myChar) วิธีนี้ช้าที่สุด เพราะต้องประมวลผลสตริงรูปแบบในระหว่างการทำงาน มีประโยชน์เฉพาะเมื่ออักขระนั้นเป็นส่วนหนึ่งของเทมเพลตขนาดใหญ่เท่านั้น

เมื่อเราได้ครอบคลุมการแปลงอักขระเดี่ยวทั้งสองทิศทางแล้ว ขั้นต่อไปคือการแปลงในทิศทางตรงกันข้าม

แปลงสตริงเป็นถ่าน

เราสามารถแปลงสตริงเป็นอักขระได้โดยใช้เมธอด charAt() ของคลาส String เมธอดนี้รับดัชนีแบบศูนย์และส่งคืนอักขระที่ตำแหน่งนั้น ดังนั้นการอ่านอักขระทุกตัวหมายความว่า ห้องน้ำping ตั้งแต่ 0 ถึง length() ลบหนึ่ง การขอค่าดัชนีที่ต่ำกว่า 0 หรือที่ length() ขึ้นไป จะทำให้เกิด StringIndexOutOfBoundsException

โปรแกรมด้านล่างนี้จะทำการวนลูปผ่านสตริง Guru99 ทีละตำแหน่งและพิมพ์อักขระแต่ละตัวพร้อมดัชนี

//Convert String to Character using string method 
package com.guru99;
 
public class StringToChar {
 
	public static void main(String[] args) 
	{
		//input String 
	      String myStr = "Guru99";
	      
	      //find string length using length method.
	      int stringLength =myStr.length();
	      
	      //for loop start 0 to total length
	      for(int i=0; i < stringLength;i++)
	      {
	    	  //chatAt method find Position and convert to character.  
	        char myChar = myStr.charAt(i);
	        
	        //print string to character
	        System.out.println("Character at "+i+" Position: "+myChar);
	      }
 
	}
 
}

ผลลัพธ์ที่คาดหวัง:

Character at 0 Position: G
Character at 1 Position: u
Character at 2 Position: r
Character at 3 Position: u
Character at 4 Position: 9
Character at 5 Position: 9

โปรดทราบว่าการแปลงประเภทข้อมูลของ String โดยตรงทำได้ยาก: `char c = (char) myStr;` ไม่สามารถคอมไพล์ได้ เนื่องจาก String เป็นอ็อบเจ็กต์ ในขณะที่ `char` เป็นประเภทข้อมูลพื้นฐาน สำหรับ String ที่ทราบอยู่แล้วว่ามีอักขระเพียงตัวเดียว คำตอบที่ถูกต้องคือ `charAt(0)`

แปลงสตริงเป็นอาร์เรย์อักขระและแปลงกลับเป็นสตริง

เมื่อต้องการใช้ตัวอักษรทุกตัวพร้อมกัน แทนที่จะใช้ทีละดัชนี ฟังก์ชัน toCharArray() จะส่งคืนค่ากลับ อาร์เรย์อักขระใหม่การแปลงอาร์เรย์นั้นกลับเป็นข้อความนั้นเป็นหน้าที่ของตัวสร้าง String(char[]) หรือ String.valueOf(char[]) และทั้งสองตัวจะคัดลอกอาร์เรย์แบบป้องกัน ดังนั้นการแก้ไขอาร์เรย์ในภายหลังจะไม่เปลี่ยนแปลงสตริง

public class StringCharArray {
  public static void main(String[] args) {
    String myStr = "Guru99";

    // the text split into its array of code units
    char[] chars = myStr.toCharArray();
    System.out.println(chars.length);
    System.out.println(chars[0]);

    // the array turned back into text
    System.out.println(new String(chars));
    System.out.println(String.valueOf(chars));

    // one range copied into an array you already own
    char[] part = new char[4];
    myStr.getChars(0, 4, part, 0);
    System.out.println(new String(part));
  }
}

ผลลัพธ์ที่คาดหวัง:

6
G
Guru99
Guru99
Guru

วิธีที่สี่ getChars(srcBegin, srcEnd, dst, dstBegin) จะคัดลอกช่วงของอักขระลงในอาร์เรย์ที่คุณมีอยู่แล้ว แทนที่จะสร้างอาร์เรย์ใหม่ ดัชนีสุดท้ายไม่รวมอยู่ด้วย ดังนั้น getChars(0, 4, part, 0) จึงให้ผลลัพธ์เป็น Guru มากกว่า Guru9. หากค่าอยู่นอกช่วงที่กำหนด จะเกิดข้อผิดพลาด IndexOutOfBoundsException

แนวทางทั้งสามแตกต่างกันหลักๆ ในสิ่งที่จัดสรรให้ ดังที่สรุปไว้ด้านล่าง

งาน โทร สิ่งที่จัดสรร
แปลงสตริงเป็นอาร์เรย์อักขระ myStr.toCharArray() อาร์เรย์ใหม่ ปลอดภัยสำหรับสตริงว่าง โดยจะคืนค่าเป็นอาร์เรย์ที่มีความยาวเป็นศูนย์
แปลงอาร์เรย์อักขระเป็นสตริง สร้างสตริงใหม่ (chars) หรือค่าของสตริง (chars) สตริงใหม่พร้อมสำเนาภายในของอาร์เรย์
ช่วงในอาร์เรย์ที่มีอยู่ myStr.getChars(0, 4, part, 0) ไม่มีอะไรใหม่ มันแค่เขียนข้อมูลลงในอาร์เรย์ที่คุณระบุ

ข้อผิดพลาดทั่วไปเมื่อแปลงอักขระและสตริงใน Java

ปัญหาส่วนใหญ่ในการแปลงเหล่านี้เกิดจากข้อผิดพลาดที่เกิดขึ้นซ้ำๆ 6 ประการ มากกว่าตัววิธีการเอง ตารางนี้แสดงข้อผิดพลาดแต่ละข้อพร้อมวิธีแก้ไข

ปัญหา ก่อให้เกิด แก้ไขปัญหา
ประเภทไม่เข้ากัน: ไม่สามารถแปลงสตริงเป็นอักขระได้ การพยายามแปลงประเภทข้อมูล เช่น char c = (char) myStr; เรียกใช้ myStr.charAt(0) แทน ไม่มีการแปลงประเภทระหว่างอ็อบเจ็กต์และชนิดข้อมูลพื้นฐาน
StringIndexOutOfBoundsException เรียกใช้ charAt() ด้วยดัชนีติดลบ หรือเรียกใช้ length() กับสตริงว่าง ตรวจสอบด้วย isEmpty() หรือเปรียบเทียบดัชนีกับความยาว (length()) ก่อนอ่าน
String.valueOf(null) โยนข้อยกเว้น NullPointerException ค่า null เปล่าๆ จะตรงกับการโอเวอร์โหลด char[] ซึ่งเป็นแบบที่เฉพาะเจาะจงที่สุด เขียน String.valueOf((Object) null) เมื่อต้องการค่า null โดยตรง
Character.toString(65) จะคืนค่าเป็น A ไม่ใช่ 65 Java 11 เพิ่มโอเวอร์โหลด Character.toString(int) ที่อ่านอาร์กิวเมนต์เป็นรหัสจุด Unicode ใช้ String.valueOf(65) หรือ Integer.toString(65) สำหรับตัวเลข 65
อีโมจิจะแสดงผลออกมาเป็นสัญลักษณ์สองตัวที่บิดเบี้ยว อักขระที่สูงกว่า U+FFFF จะใช้พื้นที่สองอักขระ โดยเป็นอักขระตัวแทนสูงตามด้วยอักขระตัวแทนต่ำ อ่านค่าด้วย codePointAt(0) จากนั้นสร้างใหม่ด้วย Character.toString(codePoint) Java 11 และใหม่กว่า
คำเตือนเกี่ยวกับการเลิกใช้งานสำหรับอักขระใหม่ (myChar) ตัวสร้าง Character(char) ถูกยกเลิกการใช้งานแล้วตั้งแต่ Java 9 และทำเครื่องหมายไว้สำหรับนำออก ใช้ Character.valueOf(myChar) หรือปล่อยให้ระบบสร้าง wrapper อัตโนมัติ

คลาส String เดียวกันนี้รองรับแบบฝึกหัดที่เกี่ยวข้องมากมาย: การกลับลำดับสตริงด้วยการเรียกซ้ำ, การเปรียบเทียบสตริงสองสตริงและ การพิมพ์ผลลัพธ์ที่จัดรูปแบบแล้ว.

คำถามที่พบบ่อย

char คือชนิดข้อมูลพื้นฐานที่เก็บหน่วยรหัส UTF-16 ขนาด 16 บิตหนึ่งหน่วย ซึ่งเขียนด้วยเครื่องหมายอัญประกาศเดี่ยว ในขณะที่ String คืออ็อบเจ็กต์ที่เก็บลำดับของหน่วยเหล่านั้น ซึ่งเขียนด้วยเครื่องหมายอัญประกาศคู่ และมีเมธอดต่างๆ เช่น length() และ charAt() ซึ่งชนิดข้อมูลพื้นฐานไม่มี

ไม่ครับ ตั้งแต่ Java 9. Character.toString(char) ถูกนำไปใช้ในรูปแบบของการเรียกใช้ String.valueOf(char) ดังนั้นทั้งสองจึงรันโค้ดเดียวกัน เลือกใช้แบบที่อ่านง่ายกว่าในสภาพแวดล้อมการทำงานของคุณ String.format(“%c”, c) เป็นวิธีเดียวที่ช้าอย่างแท้จริง

อักขระหนึ่งตัวจะเก็บหน่วยรหัส 16 บิตหนึ่งหน่วย และอิโมจิจะอยู่เหนือ U+FFFF Java แยกอักขระเหล่านั้นออกเป็นคู่ตัวแทน เพื่อให้ใช้พื้นที่สองอักขระ อ่านรหัสอักขระด้วย codePointAt() และสร้างข้อความขึ้นใหม่ด้วย Character.toChars() หรือ Character.toString(codePoint)

สาย A. Java เวอร์ชัน 11 เพิ่มการโอเวอร์โหลดของ int ที่อ่านอาร์กิวเมนต์เป็นรหัสจุด Unicode และ 65 คือรหัสจุดสำหรับ A แต่ String.valueOf(65) จะคืนค่าเป็นตัวเลข 65 แทน ซึ่งทำให้เกิดความสับสนระหว่างการเรียกใช้ทั้งสองแบบได้ง่าย

เชื่อมต่อด้วยตัวดำเนินการบวก หรือเรียกใช้ append() บน StringBuilder เมื่อการบวกเกิดขึ้นภายในลูป Java สตริงเป็นประเภทที่ไม่สามารถเปลี่ยนแปลงได้ ดังนั้นการเชื่อมต่อสตริงแต่ละครั้งจะสร้างอ็อบเจ็กต์ใหม่แทนที่จะขยายอ็อบเจ็กต์เดิม

ไม่ตั้งแต่ Java 9. สตริงแบบกะทัดรัดได้แทนที่อาร์เรย์อักขระภายในด้วยอาร์เรย์ไบต์พร้อมแฟล็กตัวเข้ารหัส ดังนั้นข้อความ Latin-1 บริสุทธิ์จึงใช้หนึ่งไบต์ต่ออักขระหนึ่งตัว ไม่มีอะไรเปลี่ยนแปลงใน API สาธารณะ และ charAt() ยังคงส่งคืนอักขระเช่นเดิม

เครื่องมือวิเคราะห์แบบคงที่ที่ใช้การเรียนรู้ของเครื่องจะแจ้งเตือนการแปลงที่น่าสงสัยซึ่งคอมไพเลอร์ยอมรับ เช่น การเรียกใช้ charAt() ที่ไม่มีการป้องกัน หรือ String.valueOf(null) ที่แปลงเป็นค่าโอเวอร์โหลดของอาร์เรย์ char โดยจะจัดอันดับผลลัพธ์ตามความน่าจะเป็น ซึ่งช่วยลดสัญญาณรบกวนจากการสแกนแบบใช้กฎธรรมดา

นักบิน GitHub โปรแกรมนี้สร้างโค้ดบรรทัดเดียวสำหรับ String.valueOf() และ charAt() ได้อย่างน่าเชื่อถือ แต่ก็ยังแสดงคำแนะนำที่ล้าสมัยจากข้อมูลการฝึกฝน เช่น ตัวสร้าง New Character(c) ที่เลิกใช้แล้ว ควรคอมไพล์ทุกคำแนะนำและอ่านคำเตือนเกี่ยวกับการเลิกใช้แล้วด้วย

สรุปโพสต์นี้ด้วย: