본문 바로가기
Java

Java 중급 1 - String

by KongJiHoon 2025. 2. 14.

1. String 클래스의 구조

public final Class String {
	
    private final char[] value;
    private final byte[] value;
}
  • String의 실제 문자열 값은 char[]에 보관된다. String 클래스는 개발자가 직접 다루기 불편한 char[]을 내부에 감추고 String 클래스를 사용하는 개발자가 편리하게 문자열을 다룰 수 있도록 다양한 기능 제공
  • 기능(메서드)
    • length() : 문자열의 길이를 반환한다.
    • charAt(int index) : 특정 인덱스의 문자를 반환한다.
    • substring(int beginIndex, int endIndex) : 문자열의 부분 문자열을 반환한다.
    • indexOf(String str) : 특정 문자열이 시작되는 인덱스를 반환한다.
    • toLowerCase() , toUpperCase() : 문자열을 소문자 또는 대문자로 변환한다.
    • trim() : 문자열 양 끝의 공백을 제거한다.
    • concat(String str) : 문자열을 더한다.

 

2. String 클래스 - 비교

package lang.string.equals;

public class StringEqualsMain1 {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println("new String() == 비교: " + (str1 == str2)); // 참조값 비교
        System.out.println("new String() == equals 비교: " + str1.equals(str2)); // 객체의 값 비교


        String str3 = "hello";
        String str4 = "hello";
        System.out.println("리터럴 == 비교 : " + (str3 == str4));
        System.out.println("리터럴 equals 비교 : " + str3.equals(str4));

    }
}

 

실행결과

new String() == 비교: false
new String() == equals 비교: true
리터럴 == 비교 : true
리터럴 equals 비교 : true

 

 

  • 리터럴의 경우 자바는 메모리 효율성과 성능 최적화를 위해 문자열 풀(String Pool)을 사용한다.
  • 자바가 실행되는 시점에 클래스에 문자열 리터럴이 있으면 문자열 풀에 String 인스턴스를 미리 만들어둔다. 이 때 같은 문자열이 있으면 만들지 않는다.
  • 풀(Pool) : 자원이 모여있는 곳을 의미한다. 프로그래밍에서 풀(Pool)은 공용 자원을 모아둔 곳을 뜻한다. 
    여러 곳에서 함께 사용할 수 있는 객체를 필요할 때 마다 생성하고, 제거하는 것은 비효율적이다. 대신에 이렇게
    문자열 풀에 필요한 String 인스턴스를 미리 만들어두고 여러곳에서 재사용할 수 있다면 성능과 메모리를 더
    최적화 할 수 있다.
    참고로 문자열 풀은 힙 영역을 사용한다. 그리고 문자열 풀에서 문자를 찾을 때는 해시 알고리즘을 사용하기 때문
    에 매우 빠른 속도로 원하는 String 인스턴스를 찾을 수 있다.
  • String 클래스는 불변객체이다.

 

  • 문자열 정보 조회
    • length() : 문자열의 길이를 반환한다.
    • isEmpty() : 문자열이 비어 있는지 확인한다. (길이가 0)
    • isBlank() : 문자열이 비어 있는지 확인한다. (길이가 0이거나 공백(Whitespace)만 있는 경우), 자바 11
    • charAt(int index) : 지정된 인덱스에 있는 문자를 반환한다.
  • 문자열 비교
    • equals(Object anObject) : 두 문자열이 동일한지 비교한다.
    • equalsIgnoreCase(String anotherString) : 두 문자열을 대소문자 구분 없이 비교한다.
    • compareTo(String anotherString) : 두 문자열을 사전 순으로 비교한다.
    • compareToIgnoreCase(String str) : 두 문자열을 대소문자 구분 없이 사전적으로 비교한다.
    • startsWith(String prefix) : 문자열이 특정 접두사로 시작하는지 확인한다.
    • endsWith(String suffix) : 문자열이 특정 접미사로 끝나는지 확인한다.
  • 문자열 검색
    • contains(CharSequence s) : 문자열이 특정 문자열을 포함하고 있는지 확인한다.
    • indexOf(String ch) / indexOf(String ch, int fromIndex) : 문자열이 처음 등장하는 위치를
      반환한다.
    • lastIndexOf(String ch) : 문자열이 마지막으로 등장하는 위치를 반환한다.
  • 문자열 조작 및 변환
    • substring(int beginIndex) / substring(int beginIndex, int endIndex) : 문자열의 부분
      문자열을 반환한다.
    • concat(String str) : 문자열의 끝에 다른 문자열을 붙인다.
    • replace(CharSequence target, CharSequence replacement) : 특정 문자열을 새 문자열로 대체
      한다.
    • replaceAll(String regex, String replacement) : 문자열에서 정규 표현식과 일치하는 부분을 새
      문자열로 대체한다.
    • replaceFirst(String regex, String replacement) : 문자열에서 정규 표현식과 일치하는 첫 번째
      부분을 새 문자열로 대체한다.
    • toLowerCase() / toUpperCase() : 문자열을 소문자나 대문자로 변환한다.
    • trim() : 문자열 양쪽 끝의 공백을 제거한다. 단순 Whitespace 만 제거할 수 있다.
    • strip() : Whitespace 와 유니코드 공백을 포함해서 제거한다. 자바 11
  • 문자열 분할 및 조합
    • split(String regex) : 문자열을 정규 표현식을 기준으로 분할한다.
    • join(CharSequence delimiter, CharSequence... elements) : 주어진 구분자로 여러 문자열을
      결합한다.
  • 기타 유틸리티
    • valueOf(Object obj) : 다양한 타입을 문자열로 변환한다.
    • toCharArray(): 문자열을 문자 배열로 변환한다.
    • format(String format, Object... args) : 형식 문자열과 인자를 사용하여 새로운 문자열을 생성한
      다.
    • matches(String regex) : 문자열이 주어진 정규 표현식과 일치하는지 확인한다.

 

StringBuilder - 가변 String

  • 불변 객체인 String의 단점은 문자를 더하거나 변경할 때마다 새로운 객체를 생성해야 한다.
  • StringBuilder는 자바에서 제공하는 가변 String
package lang.string.builder;

public class StringBuilderMain1_1 {

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("A");
        sb.append("B");
        sb.append("C");
        sb.append("D");
        System.out.println("sb = " + sb);

        sb.insert(4, "Java");
        System.out.println("sb = " + sb);

        sb.delete(4, 8);
        System.out.println("sb = " + sb);

        sb.reverse();
        System.out.println("sb = " + sb);

        //StringBuilder -> String

        String string = sb.toString();

        System.out.println("string = " + string);
    }
}

 

실행결과

sb = ABCD
sb = ABCDJava
sb = ABCD
sb = DCBA
string = DCBA
  • append() 메서드를 사용해 여러 문자열을 추가한다.
  • insert() 메서드로 특정 위치에 문자열을 삽입한다.
  • delete () 메서드로 특정 범위의 문자열을 삭제한다.
  • reverse() 메서드로 문자열을 뒤집는다.

 

  • 가변(Mutable) vs 불변(Immutable)
    String 은 불변하다. 즉, 한 번 생성되면 그 내용을 변경할 수 없다. 따라서 문자열에 변화를 주려고 할 때마다 새
    로운 String 객체가 생성되고, 기존 객체는 버려진다. 이 과정에서 메모리와 처리 시간을 더 많이 소모한다.
  • 반면에, StringBuilder 는 가변적이다. 하나의 StringBuilder 객체 안에서 문자열을 추가, 삭제, 수정할
    수 있으며, 이때마다 새로운 객체를 생성하지 않는다. 이로 인해 메모리 사용을 줄이고 성능을 향상시킬 수 있다. 
    단 사이드 이펙트를 주의해야 한다.

 

메서드 체이닝

package lang.string.chaining;

public class ValueAdder {

    private int value;

    public ValueAdder add(int addValue) {
        value += addValue;

        return this;
    }

    public int getValue() {

        return this.value;
    }
 }
  • 메소드를 고리마냥 줄줄이 엵어서 메소드를 계속해서 사용할 수 있게끔 하는 방법
  • ValueAdder에 add 메서드를 보면 return 값으로 자기 자신을 반환한다.
  • 이렇게 되면 메서드 체이닝이 가능해지는데 다음과 같은 방식이다.
 valueAdder.add(1).add(2).add(3).getValue();
  • 참조값을 x001이라고 예를들면 다음과 같이 동작한다.
    첫번째 add(1)호출이 끝나면 자기 자신을 반환하기때문에
    x001.add(2).add(3).getValue();
  • 이런식으로 반복되게된다.
  • StringBuilder또한 메서드 체이닝을 제공한다.

 

출처: 인프런 - 김영한 JAVA 중급 1편

'Java' 카테고리의 다른 글

Java 중급 1 - 열거형 Enum  (0) 2025.02.24
Java 중급 1 - Wrapper Class  (0) 2025.02.24
Java 중급 1 - 불변객체  (0) 2025.02.14
JAVA 중급 1 - Object 클래스  (0) 2025.02.14
Java 기본 - 다형성과 설계  (0) 2025.01.30