공부/Java

[Java-09] java.lang패키지 - String클래스

줭♪(´▽`) 2021. 3. 8. 21:54

1. String클래스

- 문자열을 저장하고 이를 다루는데 필요한 메서드를 함께 제공

 

1) 변경 불가능한(immutable) 클래스

- String클래스에는 문자열을 저장하기 위해 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의해둠

public final class String implements java.io.Serializable, Comparable {
    private char[] value;
    ...
}

- 생성된 String인스턴스는 읽기만 가능하고 변경은 불가능함

- 문자열간의 결합이나 추출 등은 연산 시마다 새로운 String인스턴스를 생성하는 것임 (StringBuffer클래스를 사용하는 것이 좋음)

 

2) 문자열의 비교

 

equals()   두 문자열의 내용 비교
==         인스턴스의 주소 비교

 

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");

- 문자열 리터럴 : 이미 존재하는 리터럴을 재사용 (같은 주소)

- new 연산자 : 항상 새로운 인스턴스 생성, 메모리 할당 (다른 주소)

 

3) 문자열 리터럴

- 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장됨

- 같은 내용의 문자열 리터럴은 한번만 저장됨 (한번 생성하면 내용을 변경할 수 없으므로 하나의 인스턴스를 공유)

- 해당 클래스 파일이 클래스 로더에 의해 메모리에 올라갈 때, JVM내에 있는 '상수 저장소(constant pool)'에 저장됨

 

4) 빈 문자열(empty string)

- 길이가 0인 문자열이 존재할 수 있을까? YES

- String타입은 빈 문자열로 초기화할 수 있지만 char타입은 반드시 하나의 문자를 지정해야 함

- 빈 문자열은 내부적으로 길이가 0인 char형 배열을 저장하고 있음

String s = "";	// 빈 문자열로 초기화
char c = ' ';	// 공백으로 초기화

 

 

2. String클래스의 생성자와 메서드

1) String클래스의 생성자

 

생성자 예 제 결 과
String(String s) String s = new String("Hello"); s = "Hello"
주어진 문자열(s)을 갖는 String인스턴스 생성
String(char[] value) char[] c = {'H', 'e', 'l', 'l', 'o'};
String s = new String(c);
s = "Hello"
주어진 문자열(value)을 갖는 String인스턴스 생성
String(StringBuffer buf) StringBuffer sb = new StringBuffer("Hello");
String s = new String(sb);
s = "Hello"
StringBuffer인스턴스가 갖고 있는 문자열과 같은 내용의 String인스턴스 생성

 

2) String클래스의 메서드

 

메서드 예 제 결 과
char charAt(int index) String s = "Hello"
char c = s.charAt(1);
char c2 = s.charAt(4);
c = 'e'
c2 = 'o'
지정된 위치(index)에 있는 문자를 알려줌 (index는 0부터 시작)
int compareTo(String str) int i = "aaa".compareTo("aaa");
int i2 = "aaa".compareTo("bbb");
int i3 = "bbb".compareTo("aaa");
i = 0
i2 = -1
i3 = 1
문자열(str)과 사전 순서로 비교

같으면 0
사전순으로 이전이면 음수
사전순으로 이후이면 양수
String concat(String str) String s = "Hello"
String s2 = s.concat(" World");
s2 = "Hello World"
문자열(str)을 뒤에 덧붙임
boolean contains(CharSequence s) String s = "abcedfg"
boolean b = s.contains("bc");
b = true
지정된 문자열(s)이 포함되었는지 검사
boolean endsWith(String suffix) String file = "Hello.txt";
boolean b = file.endsWith("txt");
b = true
지정된 문자열(suffix)로 끝나는지 검사
boolean equlas(Object obj) String s = "Hello";
boolean b = s.equals("Hello");
boolean b2 = s.equals("hello");
b = true
b2 = false
문자열(obj)과 String인스턴스의 문자열 비교
obj가 String이 아니거나 문자열이 다르면 false 반환
boolean equalsIgnoreCase(String str) String s = "Hello"
boolean b = s.equalsIgnoreCase("HELLO");
boolean b2 = s.equalsIgnoreCase("heLLo");
b = true
b2 = true
문자열(str)과 String인스턴스의 문자열을 대소문자 구분없이 비교
int indexOf(int ch) String s = "Hello"
int idx1 = s.indexOf('o');
int idx2 = s.indexOf('k');
idx1 = 4
idx2 = -1
주어진 문자(ch)가 문자열에 존재하는지 확인하여 위치(index)를 반환 (index는 0부터 시작)
못 찾으면 -1
int indexOf(int ch, int pos) String s = "Hello"
int idx1 = s.indexOf('e',0);
int idx2 = s.indexOf('e', 2);
idx1 = 1
idx2 = -1
주어진 문자(ch)가 문자열에 존재하는지 지정된 위치(pos)부터 확인하여 위치(index)를 반환 (index는 0부터 시작)
못 찾으면 -1
int indexOf(String str) String s = "ABCDEFG";
int idx = s.indexOf("CD");
idx = 2
주어진 문자열(str)이 문자열에 존재하는지 확인하여 위치(indx)를 반환 (index는 0부터 시작)
못 찾으면 -1
String intern() 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());
b = false
b2 = true
b3 = true
문자열을 상수풀(constant pool)에 등록
이미 상수풀에 같은 내용의 문자열이 있을 경우 그 문자열의 주소값을 반환
int lastIndexOf(int ch) String s = "java.lang.Object";
int idx1 = s.lastIndexOf(".");
int idx2 = s.indexOf(".");
idx1 = 9
idx2 = 4
지정된 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치(index)를 반환
못 찾으면 -1
int lastIndexOf(String str) String s = "java.lang.java";
int idx1 = s.lastIndexOf("java");
int idx2 = s.indexOf("java");
idx1 = 10
idx2 = 0
지정된 문자열을 문자열의 오른쪽 끝에서부터 찾아서 위치(index)를 반환
못 찾으면 -1
int length() String s = "Hello";
int length = s.length();
length = 5
문자열의 길이 반환
String replace(char old, char nw) String s = "Hello"
String s1 = s.replace('H', 'C');
s1 = "Cello"
문자열 중의 문자(old)를 새로운 문자(nw)로 바꾼 문자열을 반환
String replace(CharSequence old, CharSequence nw) String s = "Hellollo"
String s1 = s.replace("ll", "LL");
s1 = "HeLLoLLo"
문자열 중의 문자열(old)를 새로운 문자열(nw)로 모두 바꾼 문자열을 반환
String replaceAll(String regex, String replacement) String ab = "AABBAABB";
String r = ab.replaceAll("BB", "bb");
r = "AAbbAAbb"
문자열 중의 지정된 문자열(regex)과 일치하는 것을 새로운 문자열(replacement)로 모두 변경

<replace와 replaceAll의 차이점>
replace는 문자 그대로 인식
replaceAll은 정규표현식으로 인식
String replaceFirst(String regex, String replacement) String ab = "AABBAABB";
String r = ab.replaceFirst("BB", "bb");
r = "AAbbAABB"
문자열 중의 지정된 문자열(regex)과 일치하는 것 중 첫 번째 것만 새로운 문자열(replacement)로 변경
String[] split(String regex) String animals = "dog,cat,bear";
String[] arr = animals.split(",");
arr[0] = "dog"
arr[1] = "cat"
arr[2] = "bear"
문자열을 지정된 분리자(regex)로 나누어 문자열배열에 담아 반환
String[] split(String regex, int limit) String animals = "dog,cat,bear";
String[] arr = animals.split(",",2);
arr[0] = "dog"
arr[1] = "cat,bear"
문자열을 지정된 분리자(regex)로 나누어 문자열배열에 담아 반환
단, 문자열 전체를 지정된 수(limit)로 자름
boolean startsWith(String prefix) String s = "java.lang.Object";
boolean b = s.startsWith("java");
boolean b2 = s.startsWith("lang");
b = true
b2 = false
주어진 문자열(prefix)로 시작하는지 검사
String substring(int begin)
String substring(int begin, int end)
String s = "java.lang.Object";
String c = s.substring(10);
String p = s.substring(5, 9);
c = "Object"
p = "lang"
주어진 시작위치(begin)부터 끝 위치(end) 범위에 포함된 문자열을 반환
시작위치의 문자는 범위에 포함 O
끝 위치의 문자는 범위에 포함 X
(begin <= x < end)
String toLowerCase() String s = "HeLLo";
String s1 = s.toLowerCase();
s1 = "hello"
String인스턴스에 저장된 모든 문자열을 소문자로 변환하여 반환
String toUpperCase() String s = "Hello";
String s1 = s.toUpperCase();
s1 = "HELLO"
String인스턴스에 저장된 모든 문자열을 대문자로 변환하여 반환
String toString() String s = "Hello"
String s1 = s.toString();
s1 = "Hello"
String인스턴스에 저장된 문자열을 반환
String trim() String s = "        Hello World    ";
String s1 = s.trim();
s1 = "Hello World"
문자열의 왼쪽 끝과 오른쪽 끝에 있는 공백을 없앤 결과를 반환
문자열 중간에 있는 공백은 제거 X
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
static String valueOf(Object o)
String b = String.valueOf(true);
String c = String.valueOf('a');
String i = String.valueOf(100);
String l = String.valueOf(100L);
String f = String.valueOf(10f);
String d = String.valueOf(10.1);
java.util.Date dd = new java.util.Date();

String date = String.valueOf(dd);
b = "true"
c = "a"
i = "100"
l = "100"
f = "10.0"
d = "10.0"
date = "Mon Mar 8 21:30:49 KST 2021"
지정된 값을 문자열로 변환하여 반환
참조변수의 경우, toString()을 호출한 결과를 반환

 

3) join()과 StringJoiner

- join() : 여러 문자열 사이에 구분자를 넣어서 결합 <-> split()

String[] arr = {"dog", "cat", "bear"};
String str = String.join("-", arr);
// str = "dog-cat-bear"

- java.util.StringJoiner클래스를 사용하여 문자열을 결합할 수 있음

StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

delimiter : 구분자

prefix : 접두사

suffix : 접미사

StringJoiner sj = new StringJoiner(",", "[", "]");
String[] arr = { "aaa", "bbb", "ccc" };

for(String s : arr)
	sj.add(s.toUpperCase());
    
// sj.toString() => [AAA,BBB,CCC]

 

4) String.format()

- 형식화된 문자열을 만들어냄

- 기본형 값을 String으로 변환 : 빈 문자열("")을 더해주거나 valueOf()를 사용

int i = 100;
String s1 = i + "";
String s2 = String.valueOf(i);

- String을 기본형 값으로 변환 : valueOf()를 쓰거나 parse____()를 사용

int i = Integer.parseInt("100");
int i2 = Integer.valueOf("100");

 

기본형 -> 문자열 문자열 -> 기본형

String String.valueOf(boolean b)

String String.valueOf(char c)

String String.valueOf(int i)

String String.valueOf(long l)

String String.valueOf(float f)

String String.valueOf(double d)

boolean Boolean.parseBoolean(String s)
byte Byte.parseByte(String s)
short Short.parseShort(String s)
int Integer.parseInt(String s)
long Long.parseLong(String s)
float Float.parseFloat(String s)
double Double.parseDouble(String s)

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)