최근에 프로그래머스에서 제공하는 2020 카카오 블라인드 채용 코딩 테스트 문제를 풀었다. 그 중에서도 문자열 압축이라는 문제를 풀었는데, 그렇게 어렵지 않았다. 하지만, 문자열을 처리하는 부분에 대해서 취약하다는 걸 깨달을 수 있는 문제였다. 어렵지 않지만, 문자열 처리에 관해 얼마나 아는지 물어보는 문제였다.

그래서 푸는데 시간이 좀 걸리긴 했지만, 이 문제를 통해서 문자열 관련 함수를 한 번 정리하는 계기가 된 것 같다.

문자열 함수

startsWith

  • 대상 문자열이 특정 문자 또는 문자열시작하는지 체크하는 함수이다.
  • 해당 문자열로 시작되는지 여부를 확인하고 boolean에 맞춰 true/false 값을 반환한다.
  • 대소문자를 구별한다.
1
2
3
String s = "I have a book"
s.startsWith("I") // 1. true
s.startWith("book") // 2. false

endsWith

  • 대상 문자열이 특정 문자 또는 문자열끝나는지 체크하는 함수이다.
  • 해당 문자열로 끝나는지 여부를 확인하고 boolean에 맞춰 true/false 값을 반환한다.
  • 대소문자를 구별한다.
1
2
3
String s = "I have a book";
System.out.println(s.endsWith("book")); // true
System.out.println(s.endsWith("a")); // false

equals

  • 두 개의 String 문자열 값만을 비교하는 함수이다.
  • 두 문자열의 값이 같으면 true, 다르면 false를 반환한다.
1
2
3
String str1 = "Java";
String str2 = "Java";
System.out.println(str1.equals(str2)); // true

indexOf

  • 지정한 문자가 대상 문자열의 몇번째에 위치한 인덱스인지 확인한다.
  • 반환값은 지정한 문자가 위치한 인덱스를 반환한다.
  • 다만, 문자열에 지정한 문자가 여러 개 존재하는 경우, 제일 앞쪽에 나타나는 인덱스를 반환한다.
  • 지정한 문자가 문자열에 존재하지 않는 경우, -1을 반환한다.
1
2
3
String a = "I have a book";
System.out.println(a.indexOf('z')); // -1
System.out.println(a.indexOf('a')); // 3

lastIndexOf

  • 지정한 문자가 대상 문자열의 마지막 몇번째에 위치한 인덱스인지 확인한다.
  • indexOf() 함수가 앞에서부터 확인했다면, lastIndexOf() 함수는 뒤에서부터 확인하고, 찾으면 찾은 인덱스를 반환한다.
  • 지정한 문자가 문자열에 존재하지 않는 경우, -1을 반환한다.
1
2
3
String a = "I have a book";
System.out.println(a.lastIndexOf('z')); // -1
System.out.println(a.lastIndexOf('a')); // 7

replace

  • 문자열에 지정한 문자가 있으면 새로 지정한 문자로 바꿔준다.
  • replace()는 지정한 문자를 새로 지정한 문자로 바꾼 새로운 문자열을 반환한다. 따라서 기존의 문자열을 변경되지 않는다.
  • 지정한 문자가 대상 문자열에 존재하지 않으면, replace() 함수는 수행되지 않는다.
1
2
3
4
String a = "I have a book";
System.out.println(a.replace('I', 'Y')); // Y have a book
System.out.println(a); // I have a book
System.out.println(a.replace('z', 'Y')); // I have a book

replaceAll

split

  • 지정한 문자로 대상 문자열을 나누어 배열을 반환한다.
  • 문자열을 문자열 배열로 만들기 위해서는 지정 문자를 ""로 하면 된다.
  • 공백이 있는 경우, 공백도 문자열 배열에 들어간다.
1
2
3
4
5
6
7
8
9
10
11
12
String str = "A:B:C:D:abcd";
String[] split = str.split(":");
for (String s:split) System.out.print(s);
System.out.println();
System.out.println(split[4]);
// ABCDabcd
// abcd

String a = "ABCDEF G";
String[] b = a.split("");
for (String s:b) System.out.print(s);
// ABCDEF G

substring

  • 문자열에 지정한 범위에 속하는 문자열을 반환한다.
  • 시작범위의 값은 포함하고, 끝나는 범위의 값은 포함하지 않는다.
1
2
3
String a = "ABCDEFG";
System.out.println(a.substring(0,2)); // AB
System.out.println(a); // ABCDEFG

toLowerCase

  • 문자열에 존재하는 대문자를 소문자로 바꾼 새로운 문자열을 반환한다.
  • 기존에 소문자였던 문자열은 그대로 유지한다.
1
2
3
String a = "abcDEFG";
System.out.println(a.toLowerCase()); // abcdefg
System.out.println(a); // abcDEFG

toUpperCase

  • 문자열에 존재하는 소문자를 대문자로 바꾼 새로운 문자열을 반환한다.
  • 마찬가지로, 기존에 대문자였던 문자열은 그대로 유지한다.
1
2
3
String a = "abcDEFG";
System.out.println(a.toUpperCase()); // ABCDEFG
System.out.println(a); // abcDEFG

trim

  • 문자열에 존재하는 공백을 제거할 때, 사용한다.
  • 문자열의 앞, 뒤 쪽에 있는 공백만 제거할 수 있으며 가운데 존재하는 공백은 제거할 수 없고, replace() 함수를 사용해야 한다.
1
2
3
String a = "   a  aaa  a   ";
System.out.println(a.trim()); // a aaa a
System.out.println(a); // a aaa a

contains

  • 두 개의 String 값을 비교하여 비교 대상 String 문자열을 포함하고 있는지 여부를 확인한다.
  • 비교 대상 문자열을 포함하고 있으면 true, 그렇지 않으면 false를 반환한다.
1
2
3
String a = "I have a book";
System.out.println(a.contains("have")); // true
System.out.println(a.contains("z")); // false

toString

  • 문자열을 반환한다.
1
2
String a = "a";
System.out.println(a.toString()); // a

valueOf

  • 지정한 개체의 원시 값을 반환한다.
1
2
3
4
5
6
int i = 123456789;
long l = 1l;
char c = '1';
System.out.println(String.valueOf(i)); // 123456789
System.out.println(String.valueOf(l)); // 1
System.out.println(String.valueOf(c)); // 1

toString() vs valueOf()

  • toString()과의 차이점이 존재한다. 먼저, toString(), valueOf() 메소드는 모두 Object의 값을 String으로 변환하지만, 변경하고자 하는 Object가 null인 경우 다르다.
  • toString() : Null Pointer Exception(NPE) 발생.
  • valueOf() : "null"이라는 문자열로 처리한다.
    • valueOf() 함수의 원형은 다음과 같다. obj가 null인 경우, “null” 문자열을 반환한다.
1
2
3
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
  • 두 메소드의 차이는 null 값에 따른 NPE의 발생 유무이다. null로 인해 발생된 에러는 시간이 지나고, 타인의 소스인 경우 디버깅하기 어렵다. 또한, 어떤 의미를 내포하고 있는지 판단하기 어렵다. 때문에 NPE를 방지하기 위해 toString보다는 valueOf를 사용하는 것을 추천한다.

charAt

  • 지정한 index번째 문자를 반환한다.
  • 문자열의 길이보다 큰 인덱스를 지정하면 StringIndexOutOfBoundsException라는 예외가 발생한다.
1
2
3
String a = "I have a book";
System.out.println(a.charAt(0)); // I
System.out.println(a.charAt(20)); // 예외 발생.

concat

  • 문자열과 문자열을 결합해 새로운 문자열을 반환한다.
1
2
3
4
5
String a = "I";
String b = " have";
System.out.println(a.concat(b)); // I have
System.out.println(a); // I
System.out.println(b); // have

format

  • 서식 문자열을 이용해서 서식화된 문자열을 반환한다.
1
2
int i = 123456789;
System.out.println(String.format("%,d",i)); // 123,456,789

matches

  • 지정한 정규 표현식과 일치할 때, true를 반환하고 그렇지 않으면 false를 반환한다.
1
2
3
4
5
int i = 123456;
String str1 = String.format("%,d", i); // 123,456
String str2 = "123456";
boolean matcher = str1.matches(str2);
System.out.println(matcher); // false

replaceFirst

  • 문자열에 지정한 문자열이 있으면 첫 번째만 새로 지정한 문자열로 바꿔서 새로운 문자열을 반환한다.
  • 아래의 a는 "A"라는 문자열이 앞, 뒤에 등장한다. 이 경우에 replaceFirst() 메소드는 처음에 등장하는 "A"만을 "Super"라는 문자열로 바꾼다. 따라서 결과는 "SupermenA"가 된다.
  • b 문자열은 뒤에만 "A"라는 문자열이 존재하기 때문에 이게 처음 등장하는 "A"가 된다. 따라서 결과는 "menSuper"가 된다.
  • replace는 "A"라는 문자열이 등장하면 이를 모두 "Super"로 바꾼다. 따라서 결과는 "SupermenSuper"가 된다.
1
2
3
4
5
6
String a = "AmenA";
System.out.println(a.replace("A","Super")); // SupermenSuper
System.out.println(a.replaceFirst("A","Super")); // SupermenA

String b = "menA";
System.out.println(b.replaceFirst("A","Super")); menSuper

참고