Java 코딩 테스트 준비 - String과 StringBuffer, StringBuilder

기운찬곰·2023년 10월 2일
0
post-thumbnail

Overview

코딩 테스트하면 빼놓을 수 없는게 바로 문자열과 문자열 조작과 관련된 함수일 것이다. 자바에서는 String과 StringBuffer 라는 클래스가 있는데 이번시간에는 이에 대해 알아보려고 한다.


String 클래스

생성 방법

String 은 아래와 같이 생성할 수 있다. 하지만 차이가 있다.

String str1 = "abcd";
String str2 = new String("abcd");

스트링 리터럴은 자바 내부에서 리터럴 테이블로 특별히 관리하여 동일한 리터럴을 공유시킨다. 하지만 new String()으로 생성된 스트링 객체는 힙 메모리에 생성된다.

Immutable 하다

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 클래스 안에는 여러 메서드들이 존재한다. 이정도만 알고 있어도 될 듯?

  • char chatAt(int index) : index에 있는 문자 값 리턴
  • int compareTo(String str) : 두 스트링을 사전 순으로 비교하여 두 스트링이 같으면 0, 현 스트링이 str보다 먼저 나오면 음수, 아니면 양수를 리턴
  • String concat(String str) : 현재 스트링 뒤에 str를 붙인 새로운 String을 리턴
  • int length() : 스트링의 길이(문자 개수)를 리턴
  • String substring(int beginIndex (, int endIndex)) : beginIndex부터 시작하는 서브스트링 리턴. endIndex까지 있으면 beginIndex부터 시작하여 endIndex 전 위치까지 서브스트링을 반환한다.
  • String repeat(int count) : 원하는 개수만큼 현재 스트링을 반복해서 리턴해준다.
  • String[] split(String regex) : 정규식 regex에 일치하는 부분을 중심으로 스트링을 분리하고, 분리된 스트링을 배열로 해서 반환해준다.
  • String replace(CharSequnce target, CharSequence replacement) : 자신이 바꾸고 싶은 문자로 문자열을 치환시켜준다. 특이한 점은 전체를 찾아서 바꿔준다. replaceAll도 있긴 한데 차이는 replaceAll(정규식, 바꿀 문자)로 쓰인다. replaceFirst도 있다. 전체를 바꾸는 거 대신 처음 찾은 녀석만 바꿔주는 메서드다.
  • String trim() : 스트링 앞뒤 공백 문자들을 제거한 스트링 리턴
  • boolean contains(CharSequence s) : 대상 문자열에 특정 문자열이 포함되어 있는지 확인하는 함수이다. 대/소문자를 구분한다.

정적(스태틱) 메서드는 다음과 같다.

  • String.join("추가할 문자", "대상 list" 혹은 "대상 array") : 배열 혹은 리스트를 조인하는 방법
  • String.valueOf(Object obj) : 객체를 String 문자열 참조 자료형으로 형 변환

String을 char[]로, char[]를 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
  }
}

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));
}

StringBuffer 클래스

mutable 하다

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 append(String str) : str 스트링을 스트링 버퍼 뒤에 붙인다.
  • StringBuffer append(StringBuffer sb) : sb 스트링 버퍼를 현재 스트링 버퍼 뒤에 붙인다.
  • StringBuffer insert(int offset, String str) : str 스트링을 스트링 버퍼의 offset 위치에 삽입한다.
  • StringBuffer delete(int start, int end) : 스트링 버퍼 내의 start부터 end 위치 앞까지의 문자열을 삭제한다.
  • int capacity() : 스트링 버퍼의 현재 크기 리턴
  • StringBuffer replace(int start, int end, String str) : 스트링 버퍼 내의 start부터 end 위치 앞까지의 서브 스트링을 str로 대체한다.
  • StringBuffer reverse() : 현재 스트링 버퍼를 뒤집어 준다. 그리고 나서 toString()을 통해 String으로 반환해주면 문자열 뒤집기가 된다.

StringBuilder

StringBuffer와 StringBuilder 은 비슷합니다. 문자열 연산 등으로 기존 객체의 공간이 부족하게 되는 경우, 기존의 버퍼 크기를 늘리며 유연하게 동작합니다. StringBuffer와 StringBuilder 클래스가 제공하는 메서드는 서로 동일합니다.

그럼 두 클래스의 차이점은 무엇일까요? 바로 동기화 여부입니다.

  • StringBuffer는 각 메서드별로 Synchronized Keyword가 존재하여, 멀티스레드 환경에서도 동기화를 지원.
  • 반면, StringBuilder는 동기화를 보장하지 않음.

그렇기때문에 멀티스레드 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, 단일스레드 환경이라면 StringBuilder를 사용하는 것이 좋습니다. 단일 스레드환경에서 StringBuffer를 사용한다고 문제가 되는 것은 아니지만, 동기화 관련 처리로 인해 StringBuilder에 비해 성능이 좋지 않습니다.

참고 : https://12bme.tistory.com/42


참고. 문자열을 숫자형으로 형변환

참고 : https://hianna.tistory.com/524

Integer.parseInt() 를 사용하는 법

이 메소드는 문자열을 기본형 정수 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

Interger.valueOf() 를 사용하는 법

parseInt() 메소드와 마찬가지로 동작한다. 다만, parseInt() 와 가장 큰 차이점은, valueOf() 메소드는 문자열을 변환하여 Integer Object를 리턴한다는 것이다. 따라서 int로 변환하기 위해, Integer 클래스의 intValue() 메소드를 다시 한번 호출해야한다. 사실, 자동으로 형변환이 일어나서 굳이 할 필요는 없지만...


참고. String 관련 코딩테스트 문제 예시

profile
velog ckstn0777 부계정 블로그 입니다. 프론트 개발 이외의 공부 내용을 기록합니다. 취업준비 공부 내용 정리도 합니다.

0개의 댓글

관련 채용 정보