๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜

[Java] ๋ฌธ์ž์—ด ๊ด€๋ จ ํ•จ์ˆ˜ 1

by ๊ทคํ”ผํ‚ค 2025. 8. 19.

โœ… ๋ฌธ์ž์—ด ์ธ๋ฑ์‹ฑ / ์Šฌ๋ผ์ด์‹ฑ

  • charAt(i): i ๋ฒ”์œ„ ์ฒดํฌ ํ•„์š” (IndexOutOfBoundsException ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅ)
  • ๋ณต์žก๋„:
    • charAt == O(1)
    • substring == O(k) (k=์ž˜๋ผ๋‚ธ ๊ธธ์ด; Java 9+๋Š” ์ƒˆ ๋ฐฐ์—ด ๋ณต์‚ฌ)
      • substring์ด ์ž˜๋ผ๋‚ธ ๋ถ€๋ถ„์„ ์ƒˆ char ๋ฐฐ์—ด๋กœ ๋ณต์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›๋ณธ๊ณผ๋Š” ๋…๋ฆฝ์ ์ธ ๋ฌธ์ž์—ด์ด ๋˜๋‚˜ ์ž˜๋ผ๋‚ผ ๋•Œ๋งˆ๋‹ค ์ƒˆ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ ธ ๋ณต์‚ฌ ๋น„์šฉ O(k)์ด ํ•„์š”!
String s = "Hello";
char c = s.charAt(1);          // 'e'  (0-based)
String sub = s.substring(1, 4); // "ell"  (start ์ธ๋ฑ์Šค๋Š” ํฌํ•จ, end ์ธ๋ฑ์Šค ์ œ์™ธ)

 

 

โœ… ํŠน์ • ๋ฌธ์ž๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ

  • contains๋Š” ๋ถ€๋ถ„๋ฌธ์ž์—ด ๊ฒ€์ƒ‰, ๋ฌธ์ž ๊ฒ€์ƒ‰์€ indexOf(char)๊ฐ€ ๊ฐ„๋‹จ
    • contains("str")๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฒฐ๊ตญ indexOf("str") >= 0 ๋กœ์ง์„ ํ˜ธ์ถœ.
    • ๋ถ€๋ถ„๋ฌธ์ž์—ด: contains๊ฐ€ ๋” ์ฝ๊ธฐ์— ์ง๊ด€์ .
    • ๋‹จ์ผ ๋ฌธ์ž: indexOf(char)๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ณ€ํ™˜ ์—†์ด ๋ฐ”๋กœ ์“ธ ์ˆ˜ ์žˆ์–ด ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ๋œป.
  • ๋ณต์žก๋„: ํ‰๊ท  O(n) (๋ถ€๋ถ„๋ฌธ์ž์—ด ๊ธธ์ด์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง)
boolean has = s.contains("ell"); // true

// ํ•œ ๋ฌธ์ž๋ฉด:
boolean hasChar = s.indexOf('e') >= 0;

 

 

โœ… ๋ฌธ์ž์—ด์ด ๊ฐ™์€์ง€ ๋น„๊ต

  • ์ ˆ๋Œ€ == ๋กœ ๋น„๊ตํ•˜์ง€ ์•Š๊ธฐ. ํ•ญ์ƒ equals ์‚ฌ์šฉ.
    • **== ๋Š” ๋ ˆํผ๋Ÿฐ์Šค(์ฃผ์†Œ)๋ฅผ** ๋น„๊ต.
    • "ABC" ๋ฆฌํ„ฐ๋Ÿด์€ ํ’€(pool)์— ์˜ฌ๋ผ๊ฐ€์„œ ๋™์ผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, new String("ABC")๋กœ ๋งŒ๋“ค๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ๋จ
    • equals: ๋‚ด์šฉ(๋ฌธ์ž์—ด ๊ฐ’) ๋น„๊ต. ๋ฌธ์ž์—ด์ด ๊ฐ™์œผ๋ฉด true.
  • ๋ณต์žก๋„: ์ตœ์•…์ธ ๊ฒฝ์šฐ O(n)
    • equals๋Š” ๋‘ ๋ฌธ์ž์—ด์„ ์•ž์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ๋น„๊ตํ•˜๋‹ค๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ฐ”๋กœ ์ค‘๋‹จ.
    • ๋‘ ๋ฌธ์ž์—ด์ด ๋๊นŒ์ง€ ๋˜‘๊ฐ™๊ฑฐ๋‚˜ ๋งˆ์ง€๋ง‰์—๋งŒ ๋‹ค๋ฅผ ๊ฒฝ์šฐ ์ „๋ถ€ ๋น„๊ตํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ตœ์•… O(n)์ด ๋จ.
String a = "ABC", b = new String("ABC");

boolean eq = a.equals(b);               // true (๊ฐ’ ๋น„๊ต)
boolean eqIgnore = a.equalsIgnoreCase("abc"); // true

 

 

โœ… ๋ฌธ์ž์—ด ๊ธธ์ด ๋ฐ˜ํ™˜

  • UTF-16 ์ฝ”๋“œ ์œ ๋‹› ์ˆ˜๋ฅผ ๊ธธ์ด๋กœ ๋ฐ˜ํ™˜
  • ์ด๋ชจ์ง€ ๋“ฑ์˜ ์ฝ”๋“œํฌ์ธํŠธ ๊ธธ์ด๋Š” s.codePointCount(0, s.length())
  • ๋ณต์žก๋„: O(1)
int len = s.length();

 

 

โœ… ํŠน์ • ๋ฌธ์ž์˜ ์ธ๋ฑ์Šค ๊ฐ’ ์ฐพ๊ธฐ

  • ๋ฌธ์ž๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋ฉด -1 ๋ฐ˜ํ™˜.
  • ๋ณต์žก๋„: O(n)
int i1 = s.indexOf('l');        // ์ฒซ ๋ฒˆ์งธ 'l' → 2
int i2 = s.indexOf("lo");       // "lo" ์‹œ์ž‘ ์ธ๋ฑ์Šค → 3
int i3 = s.lastIndexOf('l');    // ๋งˆ์ง€๋ง‰ 'l' → 3

 

 

โœ… ๋ฌธ์ž์—ด์„ ๊ตฌ๋ถ„์ž ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ํ•ฉ์น˜๊ธฐ

  • split์€ ์ •๊ทœ์‹ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚˜๋ˆ”
    • ๋ฉ”ํƒ€๋ฌธ์ž(์˜ˆ: . | ? *๋“ฑ) ์“ฐ๋ฉด ์ด์Šค์ผ€์ดํ”„ ํ•„์š”: "\.", "\|"
    • ๋‹จ์ˆœ ๊ตฌ๋ถ„์ด๋ฉด StringTokenizer๋‚˜ ์ˆ˜๋™ ํŒŒ์‹ฑ, ๋˜๋Š” Pattern ์žฌ์‚ฌ์šฉ์œผ๋กœ ๋น„์šฉ ์ ˆ๊ฐ ๊ฐ€๋Šฅ
      • StringTokenizer: "a,b,c" ๊ฐ™์€ ๋ฌธ์ž์—ด์„ ๊ตฌ๋ถ„์ž ๋‹จ์œ„๋กœ ์ž˜๋ผ ์ˆœ์ฐจ์ ์œผ๋กœ ๊บผ๋‚ด๋Š” ๊ธฐ๋Šฅ ์ œ๊ณต. (Java์˜ ์˜›๋‚  ํด๋ž˜์Šค)
      • split(",") ๊ฐ™์€ ์ •๊ทœ์‹์€ ํ˜ธ์ถœ ๋•Œ๋งˆ๋‹ค ์ •๊ทœ์‹ ํŒจํ„ด์„ ์ƒˆ๋กœ ์ปดํŒŒ์ผํ•ด ๋น„์šฉ์ด ๋ฐœ์ƒํ•จ.
        ์ž์ฃผ ์“ฐ๋Š” ํŒจํ„ด์€ ๋ฏธ๋ฆฌ Pattern.compile(",") ํ•ด๋‘๊ณ  ์žฌ์‚ฌ์šฉํ•˜๋ฉด ๋” ํšจ์œจ์ .
  • String.join(delimiter, parts)๋Š” NullPointerException์— ์ฃผ์˜ํ•ด์•ผ ํ•จ (๋ฐฐ์—ด ์š”์†Œ๊ฐ€ null์ด๋ฉด ์˜ˆ์™ธ).
  • ๋ณต์žก๋„: O(n)
String csv = "a,b,c";

String[] parts = csv.split(",");              // ["a","b","c"]  (์ •๊ทœ์‹!)
String joined = String.join("-", parts);      // "a-b-c"

 

 

โœ… ๋ฌธ์ž์—ด ๋Œ€์†Œ๋ฌธ์ž ๋ณ€ํ™˜

  • ์ง€์—ญํ™” ์ด์Šˆ๊ฐ€ ์žˆ์œผ๋ฉด toUpperCase(Locale.ROOT) ๊ถŒ์žฅ.
    • Locale.ROOT = ์–ธ์–ด/์ง€์—ญ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ์ค‘๋ฆฝ์  ๋กœ์ผ€์ผ.
  • ๋ณต์žก๋„: O(n).
String up = s.toUpperCase();   // "HELLO"
String low = s.toLowerCase();  // "hello"

 

 

โœ… ๊ธฐ์กด ๊ฐ’์„ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์น˜ํ™˜

  • ์ •๊ทœ์‹์ด ํ•„์š” ์—†์œผ๋ฉด replace ์‚ฌ์šฉ(๋น ๋ฅด๊ณ  ์•ˆ์ „).
  • replaceAll/First๋Š” ์ •๊ทœ์‹์„ ์ธ์ž๋กœ ๋ฐ›์Œ.
  • ๋ณต์žก๋„: O(n)~O(n*k) (ํŒจํ„ด ๋ณต์žก๋„์— ์ขŒ์šฐ).
    • ์ •๊ทœ์‹ ์—”์ง„์ด ํŒจํ„ด์„ ํ•ด์„ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•จ.
    • ๋‹จ์ˆœ ์น˜ํ™˜: "abc".replace("a","b") → ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์น˜ํ™˜์ด๋ผ ๋น ๋ฆ„.
    • ์ •๊ทœ์‹ ์น˜ํ™˜: "abc".replaceAll(".","b") → ์ •๊ทœ์‹ ํ•ด์„ + ๋งค์นญ ๊ณผ์ •์ด ์ถ”๊ฐ€๋ผ ๋” ๋А๋ฆด ์ˆ˜ ์žˆ์Œ
String r1 = s.replace('l', 'L');          // ๋ฌธ์ž ์น˜ํ™˜ (๋น„์ •๊ทœ์‹)
String r2 = s.replace("ll", "LL");        // ๋ฌธ์ž์—ด ์น˜ํ™˜ (๋น„์ •๊ทœ์‹)
String r3 = s.replaceFirst("\\d+", "#");  // ์ •๊ทœ์‹ ์ฒซ ๋งค์น˜๋งŒ
String r4 = s.replaceAll("\\s+", " ");    // ์ •๊ทœ์‹ ์ „์ฒด ๋งค์น˜

 

 

โœ… ์–‘์ชฝ ๋์—์„œ ํŠน์ • ๋ฌธ์ž(ํ˜น์€ ๊ณต๋ฐฑ) ์ œ๊ฑฐ

  • trim(): ์˜›๋‚  ๋ฉ”์„œ๋“œ. 0~32 ๋ฒ”์œ„์˜ ASCII ์ œ์–ด๋ฌธ์ž + ๊ณต๋ฐฑ๋งŒ ์ œ๊ฑฐ. (์˜ˆ: \u0020 ์ŠคํŽ˜์ด์Šค)
  • strip(): Java 11 ๋„์ž…. ๋ชจ๋“  ์œ ๋‹ˆ์ฝ”๋“œ ๊ณต๋ฐฑ ์ œ๊ฑฐ. (์˜ˆ: \u2003 EM SPACE ๊ฐ™์€ ๊ฒƒ๋„ ์ œ๊ฑฐ๋จ)
    • EM SPACE (U+2003) = ์œ ๋‹ˆ์ฝ”๋“œ์—์„œ ์ •์˜๋œ ํŠน์ˆ˜ ๊ณต๋ฐฑ ๋ฌธ์ž.
      ๋ณดํ†ต ๋Œ€๋ฌธ์ž "M"์˜ ํญ๋งŒํผ ๋„“์€ ๋นˆ์นธ์„ ์˜๋ฏธ (์ผ๋ฐ˜ ์ŠคํŽ˜์ด์Šค๋ณด๋‹ค ํ›จ์”ฌ ํผ)
  • ๐Ÿ‘‰ ๊ตญ์ œํ™” ํ™˜๊ฒฝ(ํ•œ๊ธ€, ์ผ๋ณธ์–ด, ํŠน์ˆ˜ ๊ณต๋ฐฑ ํฌํ•จ)์—์„œ๋Š” strip์„ ๊ถŒ์žฅ.
  • ๋ณต์žก๋„: O(n)
String t1 = "  hi  ".trim();           // ์•ž๋’ค ๊ณต๋ฐฑ ์ œ๊ฑฐ (ASCII ๊ณต๋ฐฑ ์ค‘์‹ฌ)
String t2 = "  hi  ".strip();          // ์•ž๋’ค ์œ ๋‹ˆ์ฝ”๋“œ ๊ณต๋ฐฑ ์ œ๊ฑฐ (Java 11+)
String t3 = "---hi---".replaceAll("^-+|-+$", ""); // ํŠน์ •๋ฌธ์ž('-') ์ œ๊ฑฐ(์ •๊ทœ์‹)

 

 

โœ… ์•„์Šคํ‚ค์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ ํ˜น์€ ๋Œ€์†Œ ๋น„๊ต

  • ๋ฌธ์ž์—ด ์ •๋ ฌ/์šฐ์„ ์ˆœ์œ„๋Š” compareTo ๊ธฐ์ค€(์‚ฌ์ „์ˆœ).
  • ๋กœ์ผ€์ผ ๋ฏผ๊ฐ๋„ ํ•„์š”ํ•˜๋ฉด Collator.
  • ๋ณต์žก๋„: ํ‰๊ท  O(k) (k=๋น„๊ต ์ค‘ ์•ž๋ถ€๋ถ„์ด ๊ฐ™์€ ๊ธธ์ด).
char ch = 'A';
int code = (int) ch;          // 65 (UTF-16 ์ฝ”๋“œ ์œ ๋‹› ๊ฐ’, ASCII ํ˜ธํ™˜ ๊ตฌ๊ฐ„ ๋™์ผ)

int cmp1 = "Apple".compareTo("Banana");       // ์Œ์ˆ˜(์‚ฌ์ „์ˆœ ์•ž)
int cmp2 = "a".compareToIgnoreCase("A");      // 0
int cmp3 = Character.compare('a', 'b');       // -1

 

 

โœ… ๋ฌธ์ž์—ด ์„ฑ๋Šฅ ์•ˆ์ „ ๊ฐ€์ด๋“œ

1. ๋ฌธ์ž์—ด ๋ฐ˜๋ณต ์—ฐ๊ฒฐ์€ StringBuilder ์‚ฌ์šฉ

StringBuilder sb = new StringBuilder();
for (String p : parts) sb.append(p);
String out = sb.toString();

 

2. ๋นˆ๋ฒˆํ•œ ์ •๊ทœ์‹์€ Pattern์„ ์บ์‹ฑ

  • split, replaceAll, matches ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ •๊ทœ์‹์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ›์•„์„œ → Pattern.compile()์„ ์‹คํ–‰.
  • Pattern์€ ์ •๊ทœ์‹์„ ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผํ•ด๋†“์€ ๊ฐ์ฒด.
  • ๋ฌธ์ž์—ด๋กœ split(","), replaceAll("\s+"," ")๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ •๊ทœ์‹์ด ๋งค๋ฒˆ ์ปดํŒŒ์ผ๋จ!
  • Pattern.compile()์„ ํ•œ ๋ฒˆ ํ•ด๋‘๊ณ  ์žฌ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์œ ๋ฆฌ.
// 1) Pattern ๊ฐ์ฒด ์ƒ์„ฑ (์ •๊ทœ์‹ ์ปดํŒŒ์ผ)
Pattern pattern = Pattern.compile("\\s+"); // ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ณต๋ฐฑ์„ ์ฐพ๋Š” ํŒจํ„ด

// 2) Matcher ์ƒ์„ฑ
Matcher matcher = pattern.matcher("Hello   World   Java");

// 3) replaceAll ์‚ฌ์šฉ
String result = matcher.replaceAll(" ");
System.out.println(result); // "Hello World Java"


// ์ž์ฃผ ์“ฐ๋Š” ๋ฉ”์„œ๋“œ
// Pattern.compile(String regex) : ์ •๊ทœ์‹ ํŒจํ„ด์„ ๊ฐ์ฒด๋กœ ์ปดํŒŒ์ผ
// matcher(CharSequence input) : ์ž…๋ ฅ ๋ฌธ์ž์—ด์— ๋Œ€ํ•ด Matcher ์ƒ์„ฑ
// split(CharSequence input) : ์ž…๋ ฅ ๋ฌธ์ž์—ด์„ ์ •๊ทœ์‹ ๊ธฐ์ค€์œผ๋กœ ๋ถ„๋ฆฌ
// Pattern.matches(regex, input) : ์ •๊ทœ์‹์ด ์ž…๋ ฅ ์ „์ฒด์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ (์ •์  ๋ฉ”์„œ๋“œ)


// "String.split()๊ณผ Pattern.split()์˜ ์ฐจ์ด๋Š”?" 
// → ์ „์ž๋Š” ๋งค๋ฒˆ ํŒจํ„ด ์ปดํŒŒ์ผ, ํ›„์ž๋Š” ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผ๋œ ํŒจํ„ด ์žฌ์‚ฌ์šฉ.

 

3. ๋ฌธ์ž์—ด ๋‚ด์šฉ ๋น„๊ต ์‹œ ** == ์‚ฌ์šฉ ๊ธˆ์ง€**, ํ•ญ์ƒ equals / equalsIgnoreCase ์‚ฌ์šฉ.

 

4. ์œ ๋‹ˆ์ฝ”๋“œ ์ด์Šˆ(์ด๋ชจ์ง€, ๊ฒฐํ•ฉ ๋ฌธ์ž)์—” codePoints()๋‚˜ Normalizer ๊ณ ๋ ค.

๋Œ“๊ธ€