코딩 테스트하면 빼놓을 수 없는게 바로 문자열과 문자열 조작과 관련된 함수일 것이다. 자바에서는 String과 StringBuffer 라는 클래스가 있는데 이번시간에는 이에 대해 알아보려고 한다.
String 은 아래와 같이 생성할 수 있다. 하지만 차이가 있다.
String str1 = "abcd";
String str2 = new String("abcd");
스트링 리터럴은 자바 내부에서 리터럴 테이블로 특별히 관리하여 동일한 리터럴을 공유시킨다. 하지만 new String()으로 생성된 스트링 객체는 힙 메모리에 생성된다.
String 클래스는 immutable 하다. 즉, String 클래스를 생성하고 값을 수정 하고 싶어도 못한다.
String s = new String("Hello");
s = s.concat("Java");
s는 처음에는 Hello가 있는 객체 1234를 가리킨다. 이후 s.concat으로 Hello에 Java를 덧붙여서 새로운 객체를 만들고 s는 5678을 가리키게 되는것이다. 1234는 이후 가비지 컬렉터에 의해 자동 삭제된다. 이게 바로 immutable하다는 의미이다.
참고로, concat 안쓰고 그냥 '+' 연산으로도 쉽게 합칠 수 있다.
String 클래스 안에는 여러 메서드들이 존재한다. 이정도만 알고 있어도 될 듯?
정적(스태틱) 메서드는 다음과 같다.
참고로 String을 char array로 바꾸는 방법과 char array를 다시 String으로 변환하는 방법을 알아두면 나중에 도움이 된다. 특히 아래처럼 한 문자씩 검사하고 수정할때?
class Solution {
public String solution(String phone_number) {
char[] ch = phone_number.toCharArray(); // String -> char array
for(int i = 0; i < ch.length - 4; i ++){
ch[i] = '*';
}
return String.valueOf(ch); // char array -> String
}
}
위에처럼 toCharArray를 해서 char[]로 변환한다음 for문을 사용해도 되지만 번거롭다. 아래 처럼 charAt을 이용하면 편하다.
// Iterate over the characters of a string
String s = "Techie Delight";
// using simple for-loop
for (int i = 0; i < s.length(); i++) {
System.out.print(s.charAt(i));
}
String 클래스와 다르게 StringBuffer은 mutable 하다. 즉, String 클래스와 달리 문자열 변경 가능하다. StringBuffer 객체의 크기는 스트링 길이에 따라 가변적이다. 따라서 간단한 문자열을 처리하는 것은 String클래스를 이용하고, 문자열의 길이가 길거나 수시로 변하는 경우는 StringBuffer를 이용하는게 좋다.
아래와 같이 문자열 조작이 자유자재로 가능하다.
public class StringBufferEx {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("This");
sb.append(" is pencil"); // 문자열 덧붙이기
System.out.println(sb);
sb.insert(7, " my"); // "my" 문자열 삽입
System.out.println(sb);
sb.replace(8, 10, "your"); // "my"를 "your"로 변경
System.out.println(sb);
sb.delete(8, 13); // "your " 삭제
System.out.println(sb);
sb.setLength(4); // 스트링 버퍼 내 문자열 길이 수정
System.out.println(sb);
}
}
StringBuffer와 StringBuilder 은 비슷합니다. 문자열 연산 등으로 기존 객체의 공간이 부족하게 되는 경우, 기존의 버퍼 크기를 늘리며 유연하게 동작합니다. StringBuffer와 StringBuilder 클래스가 제공하는 메서드는 서로 동일합니다.
그럼 두 클래스의 차이점은 무엇일까요? 바로 동기화 여부입니다.
그렇기때문에 멀티스레드 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, 단일스레드 환경이라면 StringBuilder를 사용하는 것이 좋습니다. 단일 스레드환경에서 StringBuffer를 사용한다고 문제가 되는 것은 아니지만, 동기화 관련 처리로 인해 StringBuilder에 비해 성능이 좋지 않습니다.
참고 : https://12bme.tistory.com/42
참고 : https://hianna.tistory.com/524
이 메소드는 문자열을 기본형 정수 int 로 리턴한다. 문자열이 유효한 숫자를 포함하지 않는다면 NumberFormatException 예외가 던져진다.
String str1 = "123";
String str2 = "-123";
int intValue1 = Integer.parseInt(str1);
int intValue2 = Integer.parseInt(str2);
System.out.println(intValue1); // 123
System.out.println(intValue2); // -123
parseInt() 메소드와 마찬가지로 동작한다. 다만, parseInt() 와 가장 큰 차이점은, valueOf() 메소드는 문자열을 변환하여 Integer Object를 리턴한다는 것이다. 따라서 int로 변환하기 위해, Integer 클래스의 intValue() 메소드를 다시 한번 호출해야한다. 사실, 자동으로 형변환이 일어나서 굳이 할 필요는 없지만...