1. StringTokenizerชั้นเรียน

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

split()วิธี

วิธีแรกในการแยกสตริงออกเป็นหลายส่วนคือการใช้split()เมธอด นิพจน์ทั่วไปที่กำหนดสตริงการจำกัดพิเศษจะต้องผ่านเป็นอาร์กิวเมนต์ คุณจะได้เรียนรู้ว่า Regular Expression คืออะไรในภารกิจJava Multithreading

ตัวอย่าง:

รหัส ผลลัพธ์
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
ผลลัพธ์จะเป็นอาร์เรย์ของสามสตริง:
["Good ", "ws everyo", "!"]

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

StringTokenizerระดับ

Java มีคลาสพิเศษที่มีหน้าที่ทั้งหมดในการแยกสตริงออกเป็นสตริงย่อย

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

คลาสนี้มีคอนสตรัคเตอร์และเมธอดสำคัญสองเมธอด เราส่งตัวสร้างสตริงที่เราแบ่งออกเป็นส่วน ๆ และสตริงที่ประกอบด้วยชุดของอักขระที่ใช้คั่น

วิธีการ คำอธิบาย
String nextToken()
ส่งกลับสตริงย่อยถัดไป
boolean hasMoreTokens()
ตรวจสอบว่ามีสตริงย่อยเพิ่มเติมหรือไม่

คลาสนี้ชวนให้นึกถึงคลาส Scanner ซึ่งมีnextLine()และhashNextLine()เมธอด ด้วย

คุณสามารถสร้างStringTokenizerวัตถุด้วยคำสั่งนี้:

StringTokenizer name = new StringTokenizer(string, delimiters);

stringสตริงที่จะแบ่งออกเป็นส่วน ๆ อยู่ที่ไหน และdelimitersเป็นสตริง และอักขระแต่ละตัวในนั้นถือเป็นตัวคั่น ตัวอย่าง:

รหัส เอาต์พุตคอนโซล
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

โปรดทราบว่าอักขระแต่ละตัวในสตริงที่ส่งผ่านเป็นสตริงที่สองไปยังStringTokenizerคอนสตรัคเตอร์ถือเป็นตัวคั่น



2. String.format()วิธีการและStringFormatterคลาส

อีกวิธีที่น่าสนใจของคลาส String format()คือ

สมมติว่าคุณมีตัวแปรต่างๆ ที่เก็บข้อมูล คุณจะแสดงบนหน้าจอในบรรทัดเดียวได้อย่างไร ตัวอย่างเช่น เรามีข้อมูลบางส่วน (คอลัมน์ซ้าย) และเอาต์พุตที่ต้องการ (คอลัมน์ขวา):

รหัส เอาต์พุตคอนโซล
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

รหัสของคุณอาจมีลักษณะดังนี้:

รหัสโปรแกรม
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

รหัสดังกล่าวไม่สามารถอ่านได้มากนัก และถ้าชื่อตัวแปรยาวกว่านี้ โค้ดก็จะยิ่งยากขึ้นไปอีก:

รหัสโปรแกรม
class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

อ่านไม่ค่อยออกใช่ไหม

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

String.format

คลาสสตริงมีformat()เมธอดแบบสแตติก: มันให้คุณระบุรูปแบบสำหรับการประกอบสตริงกับข้อมูล ลักษณะทั่วไปของคำสั่งมีดังนี้:

String name = String.format(pattern, parameters);

ตัวอย่าง:

รหัส ผลลัพธ์
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

พารามิเตอร์format()ตัวแรกของเมธอดคือสตริงรูปแบบที่มีข้อความที่ต้องการทั้งหมดพร้อมกับอักขระพิเศษที่เรียกว่าตัวระบุรูปแบบ (เช่น%dและ%s) ในตำแหน่งที่คุณต้องการแทรกข้อมูล

เมธอดformat()จะแทนที่สิ่งเหล่านี้%sและ%dตัวระบุรูปแบบด้วยพารามิเตอร์ที่ตามหลังสตริงรูปแบบในรายการพารามิเตอร์ ถ้าเราต้องการแทรกสตริง เราก็เขียน%s. ถ้าเราต้องการแทรกตัวเลข ตัวระบุรูปแบบ%dคือ ตัวอย่าง:

รหัส ผลลัพธ์
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
sเท่ากับ"a=1, b=4, c=3"

นี่คือรายการสั้น ๆ ของตัวระบุรูปแบบที่สามารถใช้ภายในสตริงรูปแบบ:

ตัวระบุ ความหมาย
%s
String
%d
ตัวคั่น: byte, short, int,long
%f
จำนวนจริง: float,double
%b
boolean
%c
char
%t
Date
%%
%อักขระ

ตัวระบุเหล่านี้ระบุประเภทของข้อมูล แต่ก็มีตัวระบุที่ระบุลำดับของข้อมูลด้วย ในการรับอาร์กิวเมนต์ด้วยตัวเลข (การนับเริ่มจากหนึ่ง) คุณต้องเขียน " " แทน " " ตัวอย่าง:%1$d%d

รหัส ผลลัพธ์
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
sเท่ากับ"a=13, b=12, c=11"

%3$dจะได้อาร์กิวเมนต์ตัวที่ 3 %2$dจะได้อาร์กิวเมนต์ตัวที่สอง และ%dจะได้อาร์กิวเมนต์ตัวแรก ตัว ระบุรูปแบบ %sและ%dอ้างถึงอาร์กิวเมนต์โดยไม่คำนึงถึงตัวระบุเช่น%3$dหรือ%2$s



3. สระสตริง

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

ขั้นแรก สตริงที่ระบุในโค้ดต้องเก็บไว้ที่ใดที่หนึ่งใช่ไหม รหัสประกอบด้วยคำสั่ง แต่ข้อมูล (โดยเฉพาะ สตริงขนาดใหญ่) จะต้องจัดเก็บไว้ในหน่วยความจำแยกจากรหัส การอ้างอิงถึงวัตถุสตริงเท่านั้นที่ปรากฏในรหัส

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

ดังนั้น หากคุณกำหนดตัวอักษรเดียวกันให้กับStringตัวแปรหลายตัวในโค้ดของคุณ ตัวแปรเหล่านี้ก็จะมีการอ้างอิงเดียวกัน ตัวอักษรจะถูกเพิ่มStringPoolเพียงครั้งเดียว ในกรณีอื่นๆ โค้ดจะได้รับการอ้างอิงถึงสตริงที่โหลดไว้แล้วในไฟล์StringPool.

นี่คือวิธีการทำงานโดยประมาณ:

รหัส การทำงานกับ StringPool
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

นั่นคือสาเหตุที่ ตัวแปร aและbจะเก็บข้อมูลอ้างอิงเดียวกัน

intern()วิธี

และส่วนที่ดีที่สุดคือคุณสามารถเพิ่มสตริงใดๆ ลงในไฟล์StringPool. ในการทำเช่นนี้ คุณเพียงแค่เรียกใช้Stringเมธอดของintern()ตัวแปร

เมธอดintern()จะเพิ่มสตริงไปที่StringPoolถ้ายังไม่มี และจะคืนค่าอ้างอิงไปยังสตริงในไฟล์StringPool.

หากมีการเพิ่มสตริงที่เหมือนกันสองสตริง ใน StringPoolเมธอดintern()เมธอดจะคืนค่าการอ้างอิงเดียวกัน สามารถใช้เพื่อเปรียบเทียบสตริงโดยการอ้างอิง ตัวอย่าง:

รหัส บันทึก
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

คุณไม่ค่อยใช้วิธีนี้บ่อยนักแต่คนชอบถามเกี่ยวกับวิธีนี้ในการสัมภาษณ์ ดังนั้นจึงควรรู้ไว้ดีกว่าไม่รู้