본문 바로가기
JAVA/이재환의 자바 프로그래밍 입문

[Java] Ch.14 String 클래스

by ♡˖GYURI˖♡ 2023. 10. 20.
728x90

String을 선언하는 두 가지 방법

자바는 문자열을 사용할 때 String 클래스 사용

문자열은 자바 코드에서 글자들을 큰따옴표로 묶은 값

 

▼문자와 문자열

구분 자료형 기호 예시
문자 char 작은따옴표 'A', '가', '0'
문자열 String 큰따옴표 "A", "가", "0", "홍길동"

 

자바에서 문자열을 생성하는 방법은 다음과 같이 두 가지임

String str1 = new String("홍길동");	// (1)
String str = "전우치";			// (2)

단지 생성하는 방법에만 차이가 있는 것이 아님

자바 내부에서 이 두 문자열을 생성하고 처리하는 방법도 차이가 많이 남

 

(1)

  • new 연산자와 문자열 리터럴 매개변수가 있는 생성자를 이용해 객체를 힙에 만들고 그 참조 값을 변수에 대입함
  • 이 때 객체를 무조건 새로 만듦

 

(2)

  • 문자열 리터럴을 직접 대입
  • 상수를 직접 대입할 수 없기 때문에 내부적으로  new String()을 호출하여 객체를 힙에 생성하고 그 참조 값을 변수에 대입함
  • 이 때 매번 새로 만드는 것이 아니고 똑같은 문자 리터럴로 이미 만들어져 있는 객체가 있다면 그 객체의 참조 값을 변수에 대입함
public class Ex01_StringUse
{
    public static void main(String[] args)
    {
        String str1 = new String("자바프로그래밍");
        String str2 = new String("자바프로그래밍");
        String str3 = "자바프로그래밍";
        String str4 = "자바프로그래밍"; 

        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
        System.out.println(str4);

        // 문자열은 문자와 달리 내용 없이 다음과 같이 사용할 수 있습니다.
        String str5 = ""; 
    }
}

 

 

문자열형 변수의 참조 비교

비교연산자로 문자열을 비교할 수 있을까? → 불가

문자열형의 변수에는 문자열이 아닌 문자열 객체를 참조하는 id값이 들어있음

그러므로 저 비교 연산은 변수의 값을 비교하게 되고, 참조하고 있는 id값들을 비교하게 됨

문자열의 내용을 비교하는 것이 아닌 같은 객체인지 아닌지를 비교하게 되는 것임

 

public class Ex02_RefCompare
{
    public static void main(String[] args)
    {
        String str1 = new String("자바프로그래밍");
        String str2 = new String("자바프로그래밍");
        String str3 = "자바프로그래밍";
        String str4 = "자바프로그래밍"; 
        
        if (str1 == str2)
            System.out.println("str1과 str2는 동일 객체 참조");
        else 
            System.out.println("str1과 str2는 다른 객체 참조");

        if (str3 == str4)
            System.out.println("str3과 str4는 동일 객체 참조");
        else 
            System.out.println("str3과 str4는 다른 객체 참조");
        
    }
}

 

 

문자열형 변수의 내용 비교

equlas() : 내용이 단순히 같은지를 비교

compareTo() : 내용이 비교되는 대상보다 크다, 같다, 작다를 비교

compareToIgnoreCase() : 모든 문자를 대소문자 구분 없이 비교해줌

 

public class Ex03_ContentsCompare
{
    public static void main(String[] args)
    {
        String str1 = new String("Apple");
        String str2 = new String("apple");
        String str3 = new String("Banana");
        int cmp;

        // 인스턴스의 내용 비교
        if(str1.equals(str3))
            System.out.println("두 문자열은 같습니다.");
        else
            System.out.println("두 문자열은 다릅니다.");

        cmp = str1.compareTo(str2);

        if(cmp == 0)
            System.out.println("두 문자열은 일치합니다.");
        else if (cmp < 0)
            System.out.println("사전의 앞에 위치하는 문자: " + str1);
        else
            System.out.println("사전의 앞에 위치하는 문자: " + str2);

        
        if(str1.compareToIgnoreCase(str2) == 0)
            System.out.println("두 문자열은 같습니다.");
        else
            System.out.println("두 문자열은 다릅니다.");
    }
}

 

 

String 클래스의 메서드

concat() : 문자열 합치기

public class Ex04_concat
{
    public static void main(String[] args)
    {
        String str1 = "기초";
        String str2 = "프로그래밍";
        
        String str3 = str1.concat(str2);
        System.out.println(str3);

        String str4 = "자바".concat(str3);
        System.out.println(str4);
    }
}

 

indexOf() : 문자열에서 문자 찾기

public class Ex05_indexOf
{
    public static void main(String[] args)
    {
        String str = "AppleBananaOrange";
        int num1 = str.indexOf("a");
        int num2 = str.indexOf("a", num1+1);	// 찾을 문자, 찾기 시작할 위치

        System.out.println(num1);
        System.out.println(num2);
    }
}

 

substring() : 문자열 자르기

public class Ex06_substring
{
    public static void main(String[] args)
    {
        String str1 = "AppleBananaOrange";
        int num1 = str1.indexOf("Banana");	// 시작점 : 5
        int num2 = str1.indexOf("Orange");	// 시작점 : 11

        String str2 = str1.substring(num1, num2);	// substring(5, 11)은 5부터 10까지
        System.out.println(str2);

        String str3 = str1.substring(num2);		//substring(11)은 11부터 끝까지
        System.out.println(str3);
    }
}

 

length() : 문자열의 길이 구하기

public class Ex07_length
{
    public static void main(String[] args)
    {
        String str = "apple";
        for (int i=0; i<str.length(); i++)
        {
            char ch = str.charAt(i);
            if (ch == 'l')
                break;
            System.out.println(ch);
        }
    }
}

charAt() : 문자열에서 해당 인덱스의 문자를 가져올 수 있음

 

 

기본 자료형의 값을 문자열로 바꾸기

static String valueOf(boolean b)
static String valueOf(char b)
static String valueOf(double b)
static String valueOf(float b)
static String valueOf(int b)
static String valueOf(long b)

 

double형 자료를 String.valueOf()에 인수로 주는 코드

double e = 2.718281;
String se = String.valueOf(e);

 

자주 사용되는 String 크래스의 메서드들

메서드 설명
boolean contains(String s) 문자열 s를 포함하는지 조사
boolean startsWith(String s) 시작하는 문자열이 s인지 조사
boolean endsWith(String s) 끝나는 문자열이 s인지 조사
boolean isEmpty() 문자열의 길이가 0이면 true
String toLowerCase() 문자열을 모두 소문자로 변환
String toUpperCase() 문자열을 모두 대문자로 변환
String trim() 문자열 앞뒤에 있는 공백을 제거한 후 반환

 

 

문자열 대상 연산

문자열 대상 + 연산

'문자열 + 문자열'에서 +는 산술 연산을 수행할 수 없기 때문에 다음과 같이 컴파일러에 의해 자동변환이 일어나서 String 클래스의 concat() 메서드가 수행됨

 

문자열 대상 += 연산

문자열에 대한 복합 대입 연산도 컴파일러에 의해 자동 수행됨

 

문자열과 기본 자료형의 + 연산

문자열과 기본 자료형의 + 연산은 다음과 같은 복잡한 과정을 거치게 되지만 컴파일러가 자동으로 처리해줌

concat() 메서드처럼 반환형이 다시 String형이면 스트링 메서드를 계속 이어서 사용할 수 이씀

 

 

문자열 결합

concat() 메서드는 결과물에 대한 객체를 계속해서 만들어내게 됨

많은 수의 문자열을 합치면 문자열 결합에 메모리가 비효율적으로 사용됨

 

StringBuilder 클래스는 내부에 변경 가능한 변수를 가지고 있음

이 클래스를 사용하여 문자열을 연결하면 기존에 사용하던 변수의 값을 계속 확장하므로 임시 객체를 만들지 않음

새로운 메모리를 확보하고 객체를 만드는 작업을 하지 않으므로 문자열 연결 속도도 빨라짐

 

public class Ex08_StringBuilder
{
    public static void main(String[] args)
    {
        StringBuilder buf = new StringBuilder("동해물과");

        buf.append("백두산이");
        System.out.println(buf.toString());

        buf.append(12345);
        System.out.println(buf.toString());
        
        buf.delete(0, 4);
        System.out.println(buf.toString());
        
        buf.replace(4, 8, "ABC");
        System.out.println(buf.toString());

        buf.reverse();
        System.out.println(buf.toString());
    }
}

 

StringBuilder와 StringBuffer 클래스

StringBuilder와 StringBuffer 클래스는 내부에 변경 가능한 char[]를 변수로 가지고 있음

이 두 클래스를 사용하여 문자열을 연결하면 기존에 사용하던 char[] 배열이 확장되므로 임시 객체를 만들지 않음

 

기능적 공통점

  • 생성자를 포함한 메서드 수
  • 메서드 기능
  • 메서드 이름과 매개변수 선언

StringBuffer는 스레드에 안전함

그러나 모든 프로그램이 스레드 기능을 사용한 프로그래밍을 하지는 않음

따라서 스레드 안전성이 불필요한 상황에서 StringBuffer를 사용하면 성능의 저하만 유발하게 됨

그래서 StringBuilder가 등장하게 된 것임

 

 

문자열 분할

StringTokenizer는 문자열을 분할하는 클래스

분할한 문자열을 토큰이라고 함

 

String Tokenizer st = new StringTokenizer("동해물과,백두산이,마르고,닳도록", ",");
  • 첫 번째 매개변수 : 데이터로 사용될 무자열
  • 두 번째 매개변수 : 구분자, 생략 시 공백이나 탭으로 구분

StringTokenizer의 메서드

hasMoreTokens(); 토큰이 있으면 true 반환
nextToken(); 토큰을 차례로 가져옴

 

import java.util.StringTokenizer;

public class Ex09_StringTokenizer
{
    public static void main(String[] args)
    {
        StringTokenizer st1 = new StringTokenizer("a b c");
        //StringTokenizer st2 = new StringTokenizer("1,2,3", ",");

        while (st1.hasMoreTokens())
        {
            System.out.println( st1.nextToken() );
        }
    }
}