java - String 클래스

김동웅·2022년 8월 9일
0

java

목록 보기
1/2

String Class - 변경 불가능한 (immutable) 클래스

( String 클래스는 앞에 final이 붙어 있으므로 다른 클래스의 조상이 될 수 없습니다.)

  • String 클래스에는 문자열을 저장하기 위해서 문자형 배열 변수 ( char[] ) value를 인스턴스 변수로 정의해놓고 있습니다.
  • 인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열은 이 인스턴스변수( value ) ㅇ에 문자형 배열 ( char [] ) 로 저장됩니다.
public final class String implements java.io.Serializable, Comparable {
		private char[] value;
        ...
  • 생성된 String 인스턴스가 가지고 있는 문자열은 읽어 올 수만 있고, 변경될 수 없습니다.

  • 문자열 생성 시에는

  1. 문자열 리터럴을 지정하는 방법
String str1 = "abc";
String str2 = "abc";

str1 (0x100) -> "abc"
str2 (0x100)

  1. String 클래스의 생성자를 이용해서 만드는 방법
String str3 = new String("abc");
String str4 = new String("abc");

str3 (0x200) -> "abc"
str4 (0x300) -> "abc"

두가지가 있는데, 2번 방법을 사용한 경우 new 연산자에 의해서 메모리할당이 이루어지기 때문에, 항상 새로운 인스턴스가 생성된다.

그러나 1번 방법은 클래스가 메모리에 로드될 때 자동적으로 미리 생성된다.


String 클래스의 생성자와 메소드

  • String (String s)
    String(char[] value)
    : 주어진 문자열 s를 갖는 String Instance 생성

  • String(StringBuffer buf)
    : StringBuffer 인스턴스가 갖고 있는 문자열과 같은 내용의 String Instance 생성

  • char charAt(int index)
    : 지정된 위치(index)에 있는 문자를 리턴

  • int compareTo(String str)
    : 문자열 str과 사전순서로 비교하는데 같으면 0을, 사전순으로 이전이면 음수를, 이후면 양수를 리턴

int i = "aaa".compareTo("aaa");
> i = 0
int i2 = "aaa".compareTo("bbb");
> i2 = -1
int i3 = "bbb".compareTo("aaa");
> i3 = 1
  • String concat(String str)
    : 문자열 str 뒤에 덧붙임

  • boolean contains(CharSequence s)
    : 지정된 문자열(s)가 포함되었는지 검사

String s = "abcdefg";
boolean b = s.contains("bc")
> b = true
  • boolean startsWith(String prefix)
    : 주어진 문자열(prefix)로 시작하는지 검사

  • boolean endsWith(String suffix)
    : 지정된 문자열(suffix)로 끝나는지 검사

String file = "Hello.txt";
boolean b = file.endsWith("txt");
> b = true
  • boolean equals(Object obj)
    : 매개변수로 받은 문자열(obj)과 String 인스턴스의 문자열을 비교한다.
    같으면 true, 다르거나 String이 아니면 false 리턴

  • boolean equalsIgnorecase(String str)
    : 문자열 str과 String인스턴스의 문자열을 대소문자 구분없이 비교하여 같으면 true, 다르면 false 리턴

  • int indexOf(int ch)
    : 주어진 문자(ch)가 문자열에 존재하는지 확인하여 위치리턴, 없으면 -1 리턴

  • int indexOf(int ch, int pos)
    : 주어진 문자(cH)가 문자열에 존재하는지 pos위치부터 확인하여 있으면 index 리턴 없으면 -1 리턴

  • int indexOf(String str)
    : 주어진 문자열이 존재하는 확인하여 그 위치(index)를 알려준다. 없으면 -1 리턴

String s = "abcdefg";
int idx = s.indexOf("cd");

> idx = 2
  • String intern()
    : 문자열을 상수풀(Constant Pool)에 등록. 이미 상수풀에 같은 내용의 문자열이 있을경우 그 문자열의 주소값을 리턴

String s = new String("abc");
String s2 = new String("abc");
boolean b = (s==s2);
boolean b2 = s.equals(s2);
boolean b3 = (s.intern() == s2.intern());
> b1 = true, b2 = true, b3 = true
  • int lastIndexOf(int ch)
    : 지정된 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치 리턴, 못찾으면 -1 리턴
String s = "java.lang.Object";
int i = s.lastIndexOf('.');
int i2= s.indexOf('.');
> i = 9, i2 = 4
  • int lastIndexOf(String str)
    : 지정된 문자열 str을 인스턴스의 문자열 끝에서부터 찾아 위치 리턴, 못찾으면 -1 리턴
String s = "java.lang.java";
int i = s.lastIndexOf("java");
int i2 = s.indexOf("java");
> i = 10, i2 = 0
  • int length()
    : 문자열 길이 리턴

  • String replace(char old, char new)
    : 문자열에서 old Char을 new Char로 바꾼뒤 문자열 리턴

  • String replace(Charsequence old, Charseqeunce new)
    : 문자열에서 old 문자열을 new 문자열로 바꾼뒤 문자열 리턴

  • String replaceAll(String regex, String replacement)
    : 문자열 중에서 지정된 문자열(regex)과 일치하는 것을 새로운 문자열(replacement)로 모두 변경
    replace와의 차이점 : regex에는 정규식도 포함!

  • String[] split(String regex, int limit)
    : 문자열을 지정된 분리자(regex)로 나누어 문자열배열에 담아 반환한다. 단, 문자열 전체를 지정된 수로 자른다.

String animals = "dog,cat,bear";
String [] arr = animals.split(',',2);
> arr[0] = "dog" , arr[1] = "cat,bear";
  • String substring(int begin)
    : begin 부터 끝까지의 문자열 리턴

  • String substring(int begin, int end)
    : begin 부터 end-1 까지의 문자열을 리턴

public class StringTest {
    public static void main(String[] args) throws Exception {
        String fullname = "Hello.java";

        int index = fullname.indexOf('.');

        String filename = fullname.substring(0,index);
        String ext = fullname.substring(index+1);

        System.out.println(filename);
        System.out.println(ext);

    }
}
  • String toLowerCase()
    String toUpperCase()
    : 문자열 대,소문자로 변경하여 리턴

  • String toString()
    : String 인스턴스에 저장된 문자열 반환

  • String trim()
    : 문자열에서 왼쪽끝, 오른쪽 끝의 공백 없앤 후 리턴, 이떄 문자열 중간의 공백은 제거되지 않음.

  • static String valueOf(boolean b),
    static String valueOf(int i),
    static String valueOf(char c),
    static String valueOf(float f),
    static String valueOf(long l),
    static String valueOf(double d),
    static String valueOf(Object o)
    : 지정된 값을 문자열로 변경하여 리턴


join()과 StringJoiner

  • join()은 여러 문자열 사이에 구분자를 넣어서 결합. 쉽게말해 split의 역동작
String animals = "dog,cat,bear";
String [] arr = animals.split(",");
String str = String.join("-",arr);
System.out.println(str);

> dog-cat-bear
  • java.util.StringJoiner 클래스를 사용해서 결합도 가능.
StringJoiner sj = new StringJoiner("," , "[", "]");
String[] strArr = {"aaa","bbb","ccc"};

for(String s : strArr)
	sj.add(s.toUpperCase());

System.out.println(sj.toString());

> [AAA,BBB,CCC] 

String animals = "dog,cat,bear";
	String[] arr = animals.split(",");
    System.out.println(String.join("-",arr)); 
    StringJoiner sj  = new StringJoiner("/","[","]");
   
   for(String s: arr)
            sj.add(s);   
   System.out.println(sj.toString());

> dog-cat-bear
> [dog/cat/bear]

유니코드의 보충문자

  • 앞서 알아본 String class의 메소드 중에 매개변수의 타입이 char인 경우도 있고, int인 경우도 있는데 문자열을 다루는 메소드라서 매개변수의 타입이 char일 것 같은데 int인 이유는 확장된 유니코드를 다루기 위해서 이다.

유니코드 / 2bytes , 16bit 문자체계
인데 20bit로 확장하게 되었다. 그래서 하나의 문자를 char타입으로 다루지 못하고, int 타입으로 다룰 수 밖에 없게 없다.

확장에 의해 추가된 문자들을 'supplementary characters / 보충문자 ' 라고 하는데, String class의 메소드 중에서는 보충문자를 지원하는 것이 있고 지원하지 않는 것이 있음.
int ch인 것들은 보충문자를 지원하는 것이고, char ch는 보충문자를 지원하지 않는 것이다.

보충문자를 사용할 일은 거의 없으니 이정도만 알아두자


문자 인코딩 변환

getBytes(String charsetName)을 사용하면, 문자열의 문자 인코딩을 다른 인코딩으로 변경할 수 있다. 자바가 UTF-16을 사용하지만, 문자열 리터럴에 포함되는 문자들은 os의 인코딩을 사용한다.

  • 한글 Windows - CP949 사용

  • 서로 다른 문자 인코딩을 사용하는 os간에 데이터를 주고받을 때는 적절한 문자 인코딩이 필요함.


import java.util.StringJoiner;

public class StringTest {
    public static void main(String[] args) throws Exception {
        String str = "가";

        byte[] bArr = str.getBytes("CP949");
        byte[] bArr2 = str.getBytes("UTF-8");

        System.out.println("CP949 : " + joinByteArr(bArr));
        System.out.println("UTF-8 : " + joinByteArr(bArr2));

        System.out.println("CP949 : " + new String(bArr,"CP949"));
        System.out.println("UTF-8 : " + new String(bArr2,"UTF-8"));
    }

    static String joinByteArr(byte [] arr)
    {
        StringJoiner sj = new StringJoiner(":","[","]");

        for(byte b : arr)
        {
            sj.add(String.format("%02X",b));
        }
        return sj.toString();
    }
}

>
CP949 : [B0:A1]
UTF-8 : [EA:B0:80]
CP949 : 가
UTF-8 :

UTF-8은 한글 한글자를 3byte로 표현, CP949는 2byte로 표현
'가' -> utf-8 -> 0xEAB080,
'가' -> cp949 -> 0xB0A1


String.format()

  • format()은 형식화된 문자열을 만들어내는 간단한 방법.
  • printf()하고 사용법이 완전히 같음.
String str = String.format("%d 더하기 %d = %d",3,5,3+5);
> str = "3 더하기 5 = 8"

기본형 -> String

  • valueOf()사용 하는방법과 빈 문자열에 기본형을 더하는 방법 두가지가 있음
int i = 100;
String str = "" + i;
String str2 = String.valueOf(i);

String -> 기본형

  • 마찬가지로 valueOf사용하거나 %.parse%() 사용
String str = "111";
int i = Integer.valueOf(str);
int i2 = Integer.parseInt(str);

❗️ parse%()는 메소드는 문자열에 공백이나 문자가 포함되어 있는 경우 NumberFormatException이 발생할 수 있으므로 주의해야 한다. 그래서 문자열 양끝의 공백을 제거하주는 trim()을 습관적으로 사용하기도 한다.

그러나 부호를 의미하는 '+'나 소수점을 의미하는 '.'와 같은 float형 값을 뜻하는 f와 같은 자료형 접미사는 허용된다.
ex) '1.0f'를 int형 변환 메소드 parseInt()를 사용해서 변환하려한다면 예외가 발생하지만, Float.parseFloat(String s)를 사용하면 아무런 문제가 없다.

parseInt()에서는 a,b,c,d,e,f 도 사용할 수 있다.
다시말해 16진수 값으로 표현된 문자열도 변환할 수 있다!

0개의 댓글