String 클래스
String 클래스는 문자열을 다루기 위한 클래스, String 클래스는 데이터(char[], 문자 배열)와 메서드(문자열 관련)이루어져 있다. C언어의 경우 String 클래스가 존재하지 않고 문자 배열로 문자를 저장하는 것인 같지만 문자 배열을 다루데 사용되는 메서드들이 따로 존재한다.(객체지향이 아니기 때문)
public final class String implements java.io.Serializable, Comparable {
private char[] value;
...
// 문자열 관련 메서드들
}
String클래스는 내용을 변경할 수 없는 불변(immutable)클래스이다.
String a = "a";
String b = "b";
a = a + b;
- 뎃셈 연산자(+)에 의해 a + b 연산 결과가 반환되는데 문자열 변수인 a의 값을 변경하는 것이 아니다.
String 클래스는 불변 클래스이기 때문에 문자열 결합시 새로운 문자열 객체가 생성되어 문자열 변수인 a에 저장된다. 따라서 매번 새로운 객체를 생성하는 덧셈 연산자(+)를 이용한 문자열 결합은 성능이 떨어진다.
- 참조변수의 출력이나 덧셈 연산자를 이용한 참조변수와 문자열간의 결합에는 toString()이 자동적으로 호출되어 참조변수를 문자열로 대치한 후 처리한다.
문자열의 결합이나 변경이 잦다면, 내용을 변경가능한 String Buffer를 사용한다. StringBuffer클래스는 마찬가지로 문자열을 저장하고 다루기 위한 클래스지만 내용의 변경이 가능한 클래스이다. 간단한 문자열 결합은 괜찮지만 반복문 내에서 결합을 반복하거나 할 경우 사용한다.
문자열 비교
문자열 생성시 문자열 리터럴을 이용하거나 new 연산자를 이용하는 방법이 있다.
String str1 = "a"; // "a" 문자열 리터럴의 주소가 저장
String str2 = "a"; // "a" 문자열 리터럴의 주소가 저장
String str3 = new String("a"); // 새로운 String의 인스턴스가 생성
String str4 = new String("a"); // 새로운 String의 인스턴스가 생성
문자열 리터럴을 이용하여 문자열을 생성하면 하나의 리터럴을 여러 참조변수가 공유한다. new 연산자를 이용하면 항상 새로운 String의 객체가 만들어진다. 따라서 str1과 str2는 같은 주소를 가지게 되고 str3와 str4는 서로다른 인스턴스의 주소를 가지게 된다.
문자열은 내용이 변경이 불가하기 때문에 여러 참조변수가 공유해도 문제가 발생하지 않기 때문에 특별한 경우를 제외하고 new 연산자를 굳이 사용하지 않아도 된다.
대입 연산자를 사용한 문자열 비교시 주소를 비교하기 때문에 같은 내용을 가지고 있더라도 false를 반환할 수 있다.
str3 == str4; // 단순히 변수에 저장된 주소만을 비교한다.
하지만 String 클래스에는 Object 클래스에서 상속받은 equals() 메서드를 주소값이 같으면 true를 반환하고 주소값이 달라도 문자열 객체의 데이터릴 비교하도록 오버라이딩이 되어 있어 String 클래스의 equals() 메서드를 사용한다면 문자열 객체의 내용을 비교할 수 있다.
public boolean equals(Object anObject) {
// 주소를 비교
if (this == anObject) {
return true;
}
// 내용을 비교
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
문자열 리터럴은 프로그램 실생시 자동으로 생성된다.(constant pool에 저장), 같은 내용의 문자열 리터럴은 하나만 만들어지며 문자열 리터럴은 클래스의 객체이기 때문에 불변하는 상수이며 여러 참조변수에서 참조 하더라도 문제가 없다.
String str1 = "a"; // 프로그램 실생시 자동으로 생성된다.
String str2 = "a"; // 같은 리터럴은 하나만 생성, 같은 주소가 저장된다.
String str3 = "b"; // 프로그램 실생시 자동으로 생성된다.
String str4 = str1 + "a"; // 새로운 문자열은 Heap영역에 생성된다.
빈 문자열("", empty, string)
내용이 없는 문자열. 크기가 0인 char형 배열을 저장하는 문자열
String str = ""; // str을 빈 문자열로 초기화
자바에서는 크기가 0인 배열을 생성하는 것은 어느타입이나 가능
char[] chArr = new char[0] // 길이가 0인 배열
배열의 길이는 요소의 개수를 의미하고 크기는 배열이 차지하는 메모리의 사이즈를 의미한다. 자바에서는 메모리를 직접 다루지 않기 때문에 크기는 중요하지 않아 배열의 크기와 길이를 혼용하여 사용한다.
크기가 0이라서 데이터를 저장할 수 없지만 숫자를 문자로 바꾸거나 배열을 초기화 할때 null로 하는 것보다 유용하기 때문에 사용된다.
문자(char)와 문자열(String의 초기화
문자와 문자열의 기본값은 null과 유니코드의 첫번째 문자인 '\u0000'이다.
String s = null;
char c = '\u0000';
하지만 기본값이 아닌 문자열은 빈 문자열(" "), 문자는 ' ' 공백으로 초기화하는 것이 일반적이다.
String s = "";
char c = ' ';
String클래스의 생성자와 메서드
- 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인스턴스를 생성한다. |
- String클래스의 메서드
메서드 / 설명 | 예제 | 결과 |
char charAt(int index) | String s = "Hello" String n = "0123456"; char c = s.charAt(1); char c2 = n.charAt(1); |
c = 'e' c2 = '1' |
지정된 위치(index)에 있는 문자를 알려준다.(0부터 시작) | ||
int compareTo(String str) | int i = "aaa".compareTo("aaa"); int i2 = "aaa".compareTo("bbb"); int i3 = "bbb".comapreTo("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 endWith(String suffix) | String file = "Hello.txt" boolean b = file.endWith("txt") |
b = true |
지정된 문자열(suffix)로 끝나는지 검사한다. | ||
boolean equals(Objects obj) | String s = "Hello" boolean b = s.equals("Hello") |
b = true |
매개변수로 받은 문자열(obj)과 String인스턴스의 문자열을 비교한다. obj가 String이 아니거나 문자열이 다르면 false를 반환한다. | ||
boolean equalsIgnoreCase(String str) | String s = "Hello" boolean b = s.equalsIgnoreCase("HELLO") |
b = true |
문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교한다. | ||
int indexOf(char ch) | String s = "Hello" int idx1 = s.indexOf('o') |
idx1 = 4 |
주어진 문자(ch)가 문자열에 존재하는지 확인하여 위치(index)를 알려준다. 못찾으면 -1을 반환한다.(index는 0부터 시작) |
boolean contains(CharSequence s)의 매개변수 CharSequence : 인터페이스로 문자열 배열을 다루는 공통점이 있지만 공통 조상이 없는 클래스의 관계를 형성(CharBuffer, Segment, String, StringBuffer, StringBuilder)
메서드 / 설명 | 예제 | 결과 |
int indexOf(char ch. int pos) | String s = "Hello" int idx1 = s.indexOf('e', 0) |
idx = 1 |
주어진 문자(ch)가 문자열에 존재하는지 지정된 위치(pos)부터 확인하여 위치(index)를 알려준다. 못찾으면 -1을 반환한다.(index는 0부터 시작) | ||
int indexOf(String str) | String s = "ABCDEFG" int idx = s.indexOf("CD") |
idx = 2 |
주어진 문자열이 존재하는지 확인하여 그 위치(index)를 알려준다. 못찾으면 -1을 반환한다.(index는 0부터 시작) | ||
int lastIndexOf(int ch) | String s = "java.lang.Object" int idx1 = s.lastIndexOf('.') |
idx1 = 9 |
지정된 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치(index)를 알려준다. 못찾으면 -1을 반환한다. | ||
int lastIndexOf(String str) | String s = "java.lang.java" int idx1 = s.lastIndexOf("java") |
idx1 = 10 |
지정된 문자열을 인스턴스의 문자열의 끝에서부터 찾아서 위치(index)를 알려준다. 못찾으면 -1을 반환한다. | ||
int length() | String s = "Hello" int length = s.length(); |
length = 5 |
문자열의 길이를 알려준다 | ||
String[] split(String regex) | String animals = "dog,cat,bear" String[] arr = animals.split(",") |
arr[0] = "dog: arr[1] = "car" 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] = "car,bear" |
문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환한다. 단, 문자열 전체를 지정된 수(limit)로 자른다. | ||
boolean startWith(String prefix) | String s = "java.lang.Object" boolean = s.startWith("java") |
b = true |
주어진 문자열(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); *end 생략시 문자열의 길이가 생략된 걸로 간주 |
c = "Object" p = "lang" |
주어진 시작위치(begin)부터 끝 위치(end)범위에 포함된 문자열을 얻는다. 이 때 시작위치의 문자는 범위에 포함되지만, 끝위치의 문자는 포함도지 않는다. (begin <= x < end) |
||
String toLowerCase() | String s = "Hello" String s1 = s.toLowerCaser(); |
s1 = "hello" |
String인스턴스에 저장되어 있는 모든 문자열을 소문자로 변환하여 반환한다. | ||
String toUpperCase() | String s = "Hello" String s1 = s.toUpperCase(); |
s1 = "HELLO" |
String인스턴스에 저장되어있는 모든 문자열을 대문자로 변환한다. | ||
String trim() | String s = " Hello World " String s1 = s.trim(); |
s1 = "Hello World" |
문자열의 왼쪽 끝과 오른쪽 끝에 있는 공백을 없앤 결과를 반환한다. 이 때 문자열 중간에 있는 공백은 제거되지 않는다. | ||
static Stirng valueOf(boolean b) static Stirng valueOf(char c) static Stirng valueOf(int i) static Stirng valueOf(long l) static Stirng valueOf(float f) static Stirng valueOf(double d) static Stirng valueOf(Object o) |
String b = Stirng.valueOf(true) String c = Stirng.valueOf('a') String i = Stirng.valueOf(100) Stirng l = Stirng.valueOf(100L) Stirng f = Stirng.valueOf(10f) Stirng d = Stirng.valueOf(10.0) java.util.Date dd = new java.util.Date(); Stirng date = Stirng,valueOf(dd) |
b = "true" c = "a" i = "100" l = "100" f = "10.0" d = "10.0" date = "wed jan 27 21:26:29 KST 2016" |
지정된 값을 문자열로 변환하여 반환한다. 참조변수의 경우, toString()을 호출한 결과를 반환한다. |
regex(정규식, Regular Expression) : 3판 확인
문자열 결합
join()
문자열 사이에 구분자를 넣어서 결합한다.
String str1 = "a,b,c,d";
String[] arr = str1.split(","); // ','를 구분자로 나눠 배열에 저장
String str2 = String.join("-", arr); // 배열의 문자열을 '-'로 구분해서 결합
System.out.println(str2); // a-b-c-d
문자열과 기본형 간의 형변환
- 숫자를 문자열로 바꾸는 방법
int i = 100;
String str1 = i + ""; // 빈 문자열 사용하는 방법
String str2 = String.valueOf(i); // String클래스의 valueOf() 메서드 사용하는 방법
빈 문자열을 사용하는 것이 간단하고 편하지만 valueOf() 메서드를 사용하는 것이 빠르다.
- 문자열을 숫자로 바꾸는 방법
int i = Integer.parseInt("100"); // 방법 1
int i2 = Integer.valueOf("100"); // 방법 2
// Integer i2 = Integer.valueOf("100"); // valueOf()의 원래는 반환 타입이 Interger이다.
기본형과 이름이 같은 클래스를 래퍼클래스의 parse로 시작하는 매서드를 사용하면 문자열을 기본형으로 변경할 수 있다.
하지만 편리함을 위해 매서드의 이름을 통합하여 valueOf()를 사용한다. valueOf를 사용하는 것과 parseInt를 사용하는 것은 반환값의 차이와 같이 약간의 차이가 있지만 거의 같은 매서드이다.
(오토박싱 : Integer을 기본형 Int로 자동 변환)
'Java' 카테고리의 다른 글
[JAVA] 래퍼(Wrapper)클래스와 박싱 & 언박싱 (Boxing & UnBoxing) (0) | 2023.11.02 |
---|---|
[JAVA] StringBuffer 클래스 (0) | 2023.11.02 |
[JAVA] Object 클래스 (0) | 2023.10.28 |
[JAVA] 자바의 에러(error)와 예외(exception) (0) | 2023.10.25 |
[JAVA] 내부 클래스(Inner Class) (0) | 2023.10.25 |