เชี่ยวชาญ contains() ใน Java: วิธีทำการค้นหาสตริงย่อยอย่างมีประสิทธิภาพ

目次

1. บทนำ: ทำไมการค้นหาสตริงจึงสำคัญใน Java

การจัดการสตริงเป็นหนึ่งในปฏิบัติการที่ใช้บ่อยที่สุดเมื่อเขียนโปรแกรมด้วย Java
ไม่ว่าจะเป็นการตรวจสอบข้อมูลที่ผู้ใช้ป้อน, การแยกวิเคราะห์เนื้อหาไฟล์, หรือการค้นหาคำสำคัญเฉพาะ, คุณมักต้องการตรวจสอบว่าคำใดคำหนึ่งปรากฏอยู่ในสตริงที่กำหนดหรือไม่
เพื่อรองรับความต้องการเหล่านี้, Java มีเมธอดที่สะดวกชื่อ contains()
ด้วยเมธอดนี้คุณสามารถตรวจสอบได้อย่างง่ายดายว่าสตริงหนึ่ง มีส่วนหนึ่งประกอบด้วย อีกสตริงหนึ่งหรือไม่
ตัวอย่างเช่น หากคุณต้องการตรวจสอบว่าข้อความแสดงข้อผิดพลาดมีคีย์เวิร์ดเฉพาะหรือไม่, contains() จะทำให้คุณทำได้ในบรรทัดเดียวของโค้ด
โดยเฉพาะในสถานการณ์ที่ต้องจัดการข้อความจำนวนมาก—เช่น แอปพลิเคชันเว็บ, การประมวลผล API, หรือการวิเคราะห์บันทึก—เมธอด contains() ช่วยเพิ่มความอ่านง่ายและการบำรุงรักษาของโค้ดอย่างมาก
อย่างไรก็ตามก็มีประเด็นสำคัญที่ต้องคำนึงถึง เช่น ความไวต่อขนาดอักษร (case sensitivity) และความเป็นไปได้ของค่า null
บทความนี้จะอธิบายเมธอด contains() ของ Java อย่างละเอียด—from การใช้งานพื้นฐานและข้อผิดพลาดทั่วไป ไปจนถึงความแตกต่างจากเมธอดอื่น ๆ และการประยุกต์ใช้ในเชิงปฏิบัติ
เป้าหมายของเราคือการให้ข้อมูลที่เป็นประโยชน์ไม่เพียงแต่กับผู้เริ่มต้น แต่ยังกับนักพัฒนาที่ใช้งาน Java ในโครงการจริงด้วย

2. ไวยากรณ์พื้นฐานและลักษณะของเมธอด contains()

เมธอด contains() ของ Java ตรวจสอบว่าสตริง มีส่วนหนึ่งประกอบด้วย อีกสตริงหนึ่งหรือไม่
ไวยากรณ์ของมันง่ายมาก แต่มีประโยน์สูงและถูกใช้บ่อยในงานเขียนโปรแกรมประจำวัน

ไวยากรณ์พื้นฐาน

boolean result = targetString.contains(searchString);

เมธอดนี้เป็นของคลาส String และรับพารามิเตอร์เป็น CharSequence (โดยทั่วไปคือ String)
ค่าที่คืนกลับเป็น boolean: true หากสตริงเป้าหมายมีส่วนย่อยที่ระบุ, และ false หากไม่มี

ตัวอย่างโค้ด

String message = "Java programming is fun!";
boolean hasKeyword = message.contains("programming");

System.out.println(hasKeyword); // Output: true

ในตัวอย่างข้างต้น ส่วนย่อย "programming" ปรากฏในสตริงเป้าหมาย, ดังนั้น contains() จะคืนค่า true

ลักษณะของเมธอด

  • ตรวจสอบเฉพาะการจับคู่บางส่วน: หากต้องการการจับคู่ที่ตรงกันทั้งหมด ให้ใช้ equals() แทน
  • ไวต่อขนาดอักษร (Case‑sensitive): ตัวอย่างเช่น "Java" และ "java" จะถือว่าแตกต่างกัน (รายละเอียดจะอธิบายต่อในภายหลัง)
  • ไม่รองรับ regular expressions: เนื่องจากมันเพียงตรวจสอบการมีอยู่ของสตริง, การจับรูปแบบต้องใช้ matches() หรือคลาส Pattern

พฤติกรรมเมื่อส่งค่า null

การส่งค่า null ไปยัง contains() จะทำให้เกิด PointerException
ตัวอย่างเช่น โค้ดต่อไปนี้จะทำให้เกิดข้อยกเว้น:

String text = null;
System.out.println(text.contains("test")); // Exception occurs

เช่นเดียวกัน หากสตริงเป้าหมายเองเป็น null ก็จะเกิดข้อยกเว้นเดียวกัน
ดังนั้นจึงแนะนำให้ ตรวจสอบค่า null ก่อนเรียก contains() อย่างเคร่งครัด

3. ตัวอย่างการใช้งานจริงและข้อควรระวังสำคัญ

เมธอด contains() ของ Java ใช้งานง่ายและสะดวก, แต่การใช้ไม่ถูกต้องอาจทำให้เกิดบั๊กที่ไม่คาดคิดหรือโค้ดที่ไม่มีประสิทธิภาพ
ส่วนนี้จะอธิบายการใช้ contains() เบื้องต้นพร้อมกับจุดสำคัญที่คุณควรระวัง

3‑1. ตัวอย่างการใช้งานพื้นฐาน

โค้ดต่อไปนี้แสดงตัวอย่างง่าย ๆ ของการตรวจสอบว่าสตริงเป้าหมายมีคีย์เวิร์ดเฉพาะหรือไม่:

String sentence = "今日はJavaの勉強をしています。";

if (sentence.contains("Java")) {
    System.out.println("Javaが含まれています。");
} else {
    System.out.println("Javaは含まれていません。");
}

ตามที่เห็น, contains() มักถูกใช้ร่วมกับคำสั่ง if เพื่อทำการแยกสาขาตามเงื่อนไข

3‑2. ความไวต่อขนาดอักษร (Case Sensitivity)

เมธอด contains() ไวต่อขนาดอักษร
ตัวอย่างเช่น โค้ดต่อไปนี้จะคืนค่า false:

String text = "Welcome to Java";
System.out.println(text.contains("java")); // false

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

String text = "Welcome to Java";
System.out.println(text.toLowerCase().contains("java")); // true

วิธีนี้ช่วยขจัดความแตกต่างของตัวอักษรในอินพุต (เช่น อินพุตของผู้ใช้)

3-3. การจัดการ null และสตริงว่าง

หนึ่งในข้อพิจารณาที่สำคัญที่สุดเมื่อใช้ contains() คือการจัดการ null
หากสตริงเป้าหมายหรืออาร์กิวเมนต์เป็น null จะเกิด NullPointerException

String text = null;
System.out.println(text.contains("test")); // Runtime error

เพื่อหลีกเลี่ยงปัญหานี้ ควรตรวจสอบค่า null เสมอ

if (text != null && text.contains("test")) {
    // Safe to process
}

นอกจากนี้ยังต้องทราบว่า: การส่งสตริงว่าง ("") จะคืนค่า true เสมอ

String sample = "test";
System.out.println(sample.contains("")); // true

อย่างไรก็ตาม พฤติกรรมนี้มักไม่มีประโยชน์ในทางปฏิบัติและอาจทำให้เกิดบั๊กโดยไม่ได้ตั้งใจหากส่งสตริงว่างโดยบังเอิญ

3-4. ไม่รองรับการค้นหาคำหลายคำ

contains() สามารถตรวจสอบได้เพียงคำสำคัญเดียวต่อครั้ง
หากต้องการตรวจสอบหลายคำ คุณต้องเรียก contains() หลายครั้งหรือใช้ Stream API

String target = "エラーコード123:アクセス拒否";
if (target.contains("エラー") || target.contains("拒否")) {
    System.out.println("問題のあるメッセージです。");
}

หรือสำหรับชุดคำสำคัญแบบไดนามิก:

List<String> keywords = Arrays.asList("エラー", "障害", "失敗");
boolean found = keywords.stream().anyMatch(target::contains);

4. เมธอดที่มักถูกเปรียบเทียบกับ contains()

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

4-1. ความแตกต่างจาก equals(): การจับคู่แบบเต็มกับการจับคู่บางส่วน

equals() ตรวจสอบว่า สองสตริงตรงกันอย่างสมบูรณ์
ในทางตรงกันข้าม contains() ตรวจสอบการจับคู่บางส่วน

String a = "Java";
String b = "Java";

System.out.println(a.equals(b));      // true: Exact match
System.out.println(a.contains("av")); // true: Partial match

ความแตกต่างหลัก:

Comparisonequals()contains()
Match TypeExact matchPartial match
Case SensitivitySensitiveSensitive
Argument TypeObjectCharSequence

แนวทางการใช้งาน: ใช้ equals() เมื่อค่าต้องตรงกันอย่างเต็มที่ (เช่น การตรวจสอบ ID)
ใช้ contains() เมื่อการจับคู่บางส่วนยอมรับได้ (เช่น การค้นหาคำสำคัญ)

4-2. ความแตกต่างจาก indexOf(): ต้องการตำแหน่งหรือไม่

เมธอด indexOf() สามารถใช้ตรวจสอบว่ามีสับสตริงอยู่ในสตริงหรือไม่ได้เช่นกัน
ความแตกต่างคือ indexOf() จะคืนค่า ตำแหน่งเริ่มต้น ของสับสตริงหากพบ
หากไม่พบจะคืนค่า -1

String text = "Hello, Java World!";
System.out.println(text.indexOf("Java"));    // 7
System.out.println(text.indexOf("Python"));  // -1

คุณยังสามารถใช้ indexOf() เพื่อจำลองพฤติกรรมของ contains() ได้เช่นกัน:

if (text.indexOf("Java") >= 0) {
    System.out.println("It is contained.");
}

แนวทางการใช้งาน:
หากคุณไม่ต้องการตำแหน่ง contains() จะอ่านง่ายและเหมาะสมกว่า 4-3. ความแตกต่างจาก matches(): รองรับ Regular Expressions หรือไม่

เมธอด matches() ตรวจสอบว่าสตริง ตรงกับ regular expression อย่างเต็มรูปแบบ หรือไม่
ในทางตรงกันข้าม contains() ตรวจสอบเฉพาะสับสตริงแบบตัวอักษรเท่านั้นและไม่รองรับ regex

String text = "abc123";
System.out.println(text.matches(".*123")); // true
System.out.println(text.contains(".*123")); // false (not regex)

หากต้องการการจับคู่บางส่วนโดยใช้ regex ให้ใช้คลาส Pattern:

4-4. สรุปการเปรียบเทียบคุณลักษณะ

MethodPurposeReturn TypeRegex SupportUse Case
contains()Partial matchbooleanNoKeyword search
equals()Exact matchbooleanNoID/password checks
indexOf()Get match positionintNoIndex-based processing
matches()Regex matchbooleanYesFind pattern-based strings

5. กรณีการใช้งานทั่วไปและตัวอย่างโค้ด

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

5-1. การตรวจสอบความถูกต้องของอินพุตผู้ใช้ (ตรวจจับคำต้องห้าม)

ในแบบฟอร์มหรือแอปพลิเคชันแชท คุณอาจต้องตรวจจับว่ามีคำต้องห้ามบางคำรวมอยู่หรือไม่

String input = "このアプリは最悪だ";
String banned = "最悪";

if (input.contains(banned)) {
    System.out.println("不適切な言葉が含まれています。");
}

การจัดการหลายคำ NG:

List<String> bannedWords = Arrays.asList("最悪", "バカ", "死ね");
for (String word : bannedWords) {
    if (input.contains(word)) {
        System.out.println("不適切な言葉が含まれています: " + word);
        break;
    }
}

5-2. การวิเคราะห์ไฟล์บันทึก (การตรวจจับข้อความเฉพาะ)

เมื่อวิเคราะห์บันทึกระบบหรือแอปพลิเคชัน คุณอาจต้องการดึงเฉพาะบรรทัดที่มีคีย์เวิร์ดเฉพาะเช่น ERROR หรือ WARN

List<String> logs = Arrays.asList(
    "[INFO] サーバーが起動しました",
    "[ERROR] データベース接続失敗",
    "[WARN] メモリ使用率が高い"
);

for (String log : logs) {
    if (log.contains("ERROR")) {
        System.out.println("エラー発生ログ: " + log);
    }
}

5-3. การกรองสตริงในรายการ (ใช้ Stream API)

เมื่อจัดการกับชุดข้อมูลขนาดใหญ่ ใช้ Stream API เพื่อดึงเฉพาะองค์ประกอบที่มีสตริงย่อยเฉพาะ:

List<String> users = Arrays.asList("tanaka@example.com", "sato@gmail.com", "yamada@yahoo.co.jp");

List<String> gmailUsers = users.stream()
    .filter(email -> email.contains("@gmail.com"))
    .collect(Collectors.toList());

System.out.println(gmailUsers); // [sato@gmail.com]

5-4. การแยกวิเคราะห์ Header หรือ URL ของ HTTP Request

ในการพัฒนาเว็บ การกำหนดเส้นทางหรือการจัดการตามอุปกรณ์อาจต้องตรวจสอบสตริงย่อยใน User-Agent หรือ URL

String userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)";
if (userAgent.contains("iPhone")) {
    System.out.println("スマートフォンからのアクセスです。");
}

5-5. การตรวจสอบเส้นทางไฟล์หรือส่วนขยาย

เพื่อกำหนดประเภทของล์โดยใช้เส้นทางของมัน:

String filePath = "/usr/local/data/sample.csv";
if (filePath.contains(".csv")) {
    System.out.println("CSVファイルです。");
}

หมายเหตุ: สำหรับการตรวจสอบส่วนขยายไฟล์ endsWith(".csv") มักจะแม่นยำกว่า

ข้อควรพิจารณาเชิงปฏิบัติ

  • ใช้การทำให้เป็นมาตรฐาน (เช่น toLowerCase(), trim()) เมื่อความแม่นยำเป็นสิ่งจำเป็น.
  • สำหรับข้อมูลขนาดใหญ่ ควรพิจารณาใช้ Stream API หรือ regex.
  • จำไว้ว่า contains() เป็นการจับคู่บางส่วน — ควรผสานกับเงื่อนไขอื่นเพื่อความปลอดภัยของตรรกะ.

6. ข้อควรพิจารณาด้านประสิทธิภาพ

แม้ว่าวิธี contains() จะให้ความอ่านง่ายและความเรียบง่ายที่ดีเยี่ยม แต่คุณต้องพิจารณา ผลกระทบต่อประสิทธิภาพ เมื่อจัดการกับชุดข้อมูลขนาดใหญ่หรือดำเนินการซ้ำหลายครั้ง
ส่วนนี้อธิบายค่าใช้จ่ายการประมวลผลของ contains() และแนวทางทางเลือกเพื่อเพิ่มประสิทธิภาพ

6-1. พฤติกรรมภายในและความซับซ้อนของเวลาในการทำงานของ contains()

เมธอด contains() จะค้นหาสตริงเป้าหมาย อย่างต่อเนื่องจากจุดเริ่มต้น เพื่อหาสตริงย่อย
ภายใน มันพึ่งพาเมธอด indexOf() และความซับซ้อนของเวลาในกรณีที่แย่ที่สุดคือ:
O(n * m)
– n = ความยาวของสตริงเป้าหมาย
– m = ความยาวของสตริงที่ค้นหา

ตัวอย่างของการประมวลผลหนัก:

for (String line : hugeTextList) {
    if (line.contains("error")) {
        // processing
    }
}

สิ่งนี้สามารถส่งผลกระทบต่อประสิทธิภาพอย่างมากเมื่อทำซ้ำในลูปขนาดใหญ่

6-2. เทคนิคการปรับปรุงประสิทธิภาพในการค้นหาบ่อยครั้ง

เมื่อใช้ contains() ซ้ำในชุดข้อมูลขนาดใหญ่ เทคนิคต่อไปนี้สามารถเพิ่มความเร็วการประมวลผลได้:

• แปลงสตริงทั้งหมดเป็นตัวพิมพ์เล็กล่วงหน้า

แทนการเรียก toLowerCase() ในแต่ละการเปรียบเทียบ ให้ทำการทำให้เป็นมาตรฐานล่วงหน้า:

List<String> normalizedList = originalList.stream()
    .map(String::toLowerCase)
    .collect(Collectors.toList());
• ใช้ Stream API กับ parallel() เพื่อการประมวลผลแบบขนาน

ใช้คอร์ของ CPU เพื่อเร่งการค้นหา:

List<String> result = hugeTextList.parallelStream()
    .filter(line -> line.contains("keyword"))
    .collect(Collectors.toList());
• ใช้ regular expressions สำหรับรูปแบบการค้นหาที่ซับซ้อน

หากเงื่อนไขมีความซับซ้อนและสามารถแสดงออกด้วย regex เดียว Pattern อาจทำงานได้ดีกว่า:

Pattern pattern = Pattern.compile("error|fail|fatal");
for (String log : logs) {
    if (pattern.matcher(log).find()) {
        // matched
    }
}

6-3. ข้อพิจารณาเกี่ยวกับประสิทธิภาพหน่วยความจำและการนำกลับมาใช้ใหม่

การดำเนินการที่แปลงสตริงบ่อยครั้ง เช่น toLowerCase() หรือ substring() — อาจสร้าง วัตถุสตริงที่ไม่จำเป็นจำนวนมาก ซึ่งส่งผลต่อการใช้งานหน่วยความจำ นี่เป็นเรื่องสำคัญโดยเฉพาะสำหรับแอปพลิเคชันที่ทำงานยาวนานหรือการประมวลผลฝั่งเซิร์ฟเวอร์ ประเด็นสำคัญ:

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

7. การเปรียบเทียบกับภาษาการเขียนโปรแกรมอื่น ๆ

เมธอด contains() ของ Java ให้การจับคู่ส่วนย่อยของสตริงที่เรียบง่ายและเชื่อถือได้ แต่ภาษาอื่น ๆ ก็มีคุณสมบัติคล้ายกันพร้อมลักษณะเฉพาะของตัวเอง ส่วนนี้เปรียบเทียบการตรวจสอบส่วนย่อยของสตริงใน Python, JavaScript และ C# เพื่อเน้นความแตกต่างและความคล้ายคลึง

7-1. Python: การจับคู่บางส่วนแบบเรียบง่ายด้วยตัวดำเนินการ in

ใน Python คุณสามารถตรวจสอบการรวมส่วนย่อยของสตริงโดยใช้ตัวดำเนินการ in:

text = "Hello, Python!"
if "Python" in text:
    print("含まれています")

ไวยากรณ์นี้สามารถอ่านได้ง่ายมาก — เกือบเหมือนภาษาธรรมชาติ — และต้องใช้การเรียนรู้ขั้นต่ำ ความแตกต่างและหมายเหตุ:

  • in เป็นตัวดำเนินการของภาษา ไม่ใช่เมธอด
  • Python ก็เปรียบเทียบสตริงแบบแยกแยะตัวพิมพ์ใหญ่-เล็กเช่นกัน
  • None จะทำให้เกิดข้อยกเว้น; ต้องตรวจสอบ null

7-2. JavaScript: การจับคู่บางส่วนด้วย includes()

ใน JavaScript (ES6+) คุณสามารถใช้เมธอด includes():

const text = "JavaScript is fun";
console.log(text.includes("fun")); // true

เมธอดนี้คล้ายกับ contains() ของ Java มากและง่ายต่อการย้ายในใจ ความแตกต่างและหมายเหตุ:

  • การส่ง undefined จะไม่โยนข้อยกเว้น; มันเพียงแค่คืนค่า false
  • includes() ยังทำงานกับอาร์เรย์ ทำให้มีความยืดหยุ่นมากขึ้น

7-3. C#: Contains() คล้ายกับ Java

C# ก็มีเมธอด Contains() ที่มีพฤติกรรมคล้ายกับ Java:

string text = "Welcome to C#";
bool result = text.Contains("C#");

ความแตกต่างและหมายเหตุ:

  • Contains() ของ C# แยกแยะตัวพิมพ์ใหญ่-เล็กโดยค่าเริ่มต้น แต่คุณสามารถเพิกเฉยตัวพิมพ์ใหญ่-เล็กโดยใช้ StringComparison.OrdinalIgnoreCase
  • การส่ง null จะเรียก ArgumentNullException

7-4. ตารางเปรียบเทียบข้ามภาษา

LanguageExample SyntaxCase SensitivityNotes
Java"abc".contains("a")SensitiveThrows exception on null
Python"a" in "abc"SensitiveMost intuitive syntax
JavaScript"abc".includes("a")SensitiveAlso works for arrays
C#"abc".Contains("a")Sensitive (configurable)Comparison mode can be chosen

สรุป: เลือกไวยากรณ์ที่เหมาะสมสำหรับกรณีใช้งานของคุณ

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

8. คำถามที่พบบ่อย (FAQ)

ด้านล่างนี้คือคำถามที่พบบ่อยเกี่ยวกับเมธอด contains() ของ Java — ช่วยให้คุณเข้าใจจุดที่ซับซ้อนและหลีกเลี่ยงหลุมพรางทั่วไป

Q1. contains() แยกแยะตัวพิมพ์ใหญ่-เล็กหรือไม่?

ใช่ มันแยกแยะตัวพิมพ์ใหญ่-เล็ก ตัวอย่างเช่น "Java".contains("java") คืนค่า false วิธีแก้ไข:

String input = "Welcome to Java";
boolean result = input.toLowerCase().contains("java");

Q2. ฉันสามารถตรวจสอบการจับคู่บางส่วนโดยใช้ regular expressions ได้อย่างไร?

contains() ไม่รองรับ regular expressions ใช้ matches() หรือคลาส Pattern แทน ตัวอย่าง (การตรวจสอบรูปแบบตัวเลข):

import java.util.regex.Pattern;
import java.util.regex.Matcher;

String text = "注文番号: A123456";
Pattern pattern = Pattern.compile("A\d+");
Matcher matcher = pattern.matcher(text);

if (matcher.find()) {
    System.out.println("パターンに一致しました。");
}

Q3. จะเกิดอะไรขึ้นหากฉันเรียก contains() บนค่า null?

จะเกิด NullPointerException

String target = null;
System.out.println(target.contains("test")); // Error

วิธีแก้:

if (target != null && target.contains("test")) {
    System.out.println("含まれています。");
}

Q4. จะเกิดอะไรขึ้นหากฉันส่งสตริงว่าง (“”) ไปยัง contains()?

มันจะคืนค่า true เสมอ

String text = "Java";
System.out.println(text.contains("")); // true

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

Q5. contains() สามารถค้นหาคำหลายคำพร้อมกันได้หรือไม่?

ไม่ได้. การเรียกแต่ละครั้งจะตรวจสอบเพียงคำเดียวเท่านั้น

String text = "本日はシステムエラーが発生しました";
if (text.contains("エラー") || text.contains("障害") || text.contains("失敗")) {
    System.out.println("問題が検出されました。");
}

วิธีการแบบไดนามิก:

List<String> keywords = Arrays.asList("エラー", "障害", "失敗");
boolean found = keywords.stream().anyMatch(text::contains);

Q6. ควรใช้ contains() หรือ indexOf() เมื่อไหร่?

contains() คืนค่าเป็นบูลีน, ส่วน indexOf() คืนค่าเป็นดัชนีเชิงตัวเลข

  • ใช้ contains() เมื่อคุณต้องการเพียงรู้ว่ามีสตริงย่อยอยู่หรือไม่
  • ใช้ indexOf() เมื่อคุณต้องการตำแหน่งด้วย
    String text = "Error: Disk full";
    if (text.contains("Error")) {
        int pos = text.indexOf("Error");
        System.out.println("Position: " + pos);
    }
    

9. สรุป

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

  • ไวยากรณ์พื้นฐานและค่าที่คืนกลับ
  • ความไวต่อขนาดตัวอักษรและวิธีจัดการ
  • การจัดการค่า null และสตริงว่าง
  • ความแตกต่างจากวิธีเปรียบเทียบสตริงอื่นๆ
  • กรณีการใช้งานจริง: การตรวจสอบ, การค้นหาบันทึก, การประมวลผล Stream
  • ข้อพิจารณาด้านประสิทธิภาพและเทคนิคการปรับแต่ง
  • การเปรียบเทียบกับ Python, JavaScript, และ C#
  • คำถามที่พบบ่อยและเคล็ดลับการแก้ปัญหา

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