일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- string
- bit manipulation
- Number Theory
- 구현
- greedy
- sorting
- implement
- Stack
- array
- Method
- two pointers
- SQL
- 파이썬
- Math
- Binary Tree
- Class
- Counting
- 코테
- 코딩테스트
- hash table
- Binary Search
- 자바
- geometry
- database
- java
- Tree
- Matrix
- dynamic programming
- simulation
- Data Structure
- Today
- Total
코린이의 소소한 공부노트
String 클래스 본문
[String 클래스]
1. 문자열을 다루기 위한 클래스
2. 내부적으로 char[]을 가지고 있다.
3. 내용을 변경할 수 없는 불변(immutable) 클래스다. 즉 한번 생성되면 수정할 수 없다. 아래처럼 문자열 결합을 해서 수정하는 것 같아 보이는 코드도 메모리에서는 우리의 생각과는 다른 일이 일어난다.
- 문자열 결합(+)은 계속 String 객체를 만들어 내서 성능이 떨어진다. 문자열의 결합이나 변경이 잦다면, 내용을 변경할 수 있는 StringBuffer 클래스를 사용하는 것이 좋다.
[문자열을 생성하는 방법]
// 1. 기본형처럼 생성
String s1 = "abc"; // 문자열 리터럴 "abc"의 주소가 s1에 저장됨
String s2 = "abc"; // 문자열 리터럴 "abc"의 주소가 s2에 저장됨
// 2. new 연산자 이용
String s3 = new String("abc"); // 새로운 String 객체 생성
String s4 = new String("abc"); // 새로운 String 객체 생성
2가지 생성 방법의 차이점은 메모리에서 잘 나타난다.
s1과 s2는 같은 객체를 가리키기 때문에 등가 비교 연산의 결과가 true지만, s3과 s4는 각각 다른 객체를 가리키기 때문에 등가 비교 연산의 결과가 false다. s3과 s4의 비교 연산 결과가 true인 것을 원한다면 equals()를 써야 한다.
s1.equals(s2); // true
s3.equals(s4); // true
equals()는 객체의 주소를 따라가 그 안에 담긴 내용을 비교하기 때문에 다른 객체를 가리키고 있는 s3과 s4의 비교 결과가 true가 나올 수 있는 것이다. 문자열은 객체의 주소가 중요한 것이 아닌 내용이 중요한 것이기 때문에 비교 연산을 등가 비교 연산자(==)보다 equals()로 하는 것이 좋다.
각각의 장단점이 있겠지만, 메모리 관점에서 본다면 문자열은 내용 변경 불가이기 때문에 특별한 경우를 제외한다면 new 연산자를 이용해서 매번 새로운 String 객체를 만드는 것보다 1번처럼 같은 내용이면 공유하는 것이 더 좋을듯싶다.
[constant pool, 상수 저장소]
1. 문자열 리터럴은 프로그램 실행 시 자동으로 생성되어 상수 저장소에 저장된다.
2. 같은 내용의 문자열 리터럴은 1개만 만들어진다.
String s1 = "a";
String s2 = "a";
String s3 = "a";
String s4 = "b";
이렇게 문자열을 생성하게 되면 s1, s2, s3에는 "a"의 위치가 저장되고, s4는 "b"의 위치가 저장된다. 즉 같은 문자열 리터럴을 담고 있는 String 참조 변수는 1개의 문자열 리터럴을 공유한다. 앞서 언급했듯이, 문자열은 불변이기 때문에 매번 새로운 객체를 만드는 것보다 같은 것을 공유하는 것이 더 효율적이기 때문이다.
[빈 문자열("", empty string)]
1. 내용이 없는 문자열
2. 길이가 0인 char형 배열을 저장하는 문자열
- 길이가 0인 배열을 생성하는 것은 어느 타입이나 가능하다
char[] chArr = new char[0]; // 빈 char 배열
int[] iArr = {}; // 빈 int 배열
String s = ""; // 빈 문자열
[문자와 문자열의 초기화]
// 기본값으로 초기화
String s = null;
char c = '\u0000'; // 유니코드의 첫번째 문자
// 더 유용한 초기화
String s = ""; // 빈 문자열
char c = ' '; // 공백
[생성자]
String s = new String("Hello");
String(String s)
- 주어진 문자열(s)을 갖는 String 인스턴스를 생성
char[] c = {'H', 'e', 'l', 'l', 'o'};
String s = new String(c);
String(char[] value)
- 주어진 문자열(value)을 갖는 String 인스턴스를 생성
- 이것과 반대로 String을 char[]로 바꿀 때는 toCharArray 메서드를 이용
StringBuffer sb = new StringBuffer("Hello");
String s = new String(sb);
String(StringBuffer buf)
- StringBuffer 인스턴스가 갖고 있는 문자열과 같은 내용의 String 인스턴스를 생성
- StringBuffer는 내용 변경이 가능한 문자열 클래스
[메서드]
String s = "Hello123";
char c1 = s.charAt(1); // 'e'
char c2 = s.charAt(6); // '2'
char charAt(int index)
- 지정된 위치(index)에 있는 문자를 반환
- index는 0부터 시작
int i1 = "bbb".compareTo("aaa"); // 1
int i2 = "bbb".compareTo("bbb"); // 0
int i3 = "bbb".compareTo("ccc"); // -1
int compareTo(String str)
- 문자열(str)과 사전 순서로 비교
- 같으면 0 반환
- 사전 순으로 이전이면 음수 반환
- 사전 순으로 이후면 양수 반환
String s = "Hello";
String s2 = s.concat(" world"); // s2 = "Hello world"
String concat(String str)
- 문자열(str)을 뒤에 덧붙임
String s = "abcde";
boolean b = s.contains("bcd"); // b = true
boolean contains(CharSequence s)
- 지정된 문자열(s)이 포함되어있는지 확인
- 포함되어있으면 true, 아니면 false 반환
String s = "abcde";
boolean b = s.endsWith("de"); // b = true
boolean endsWith(String suffix)
- 지정된 문자열(suffix)로 끝나는지 확인
- 해당 문자열로 끝난다면 true, 아니면 false 반환
- 특정 문자열로 시작하는지 확인하는 메서드는 startsWith
String s = "abcde";
boolean b1 = s.equals("abcde"); // b1 = true
boolean b2 = s.equals("ABCDE"); // b2 = false
boolean equals(Object obj)
- 매개변수로 받은 문자열(obj)과 String 인스턴스의 문자열을 비교
- 내용이 같으면 true, 다르면 false 반환
String s = "abcde";
boolean b1 = s.equalsIgnoreCase("abcde"); // b1 = true
boolean b2 = s.equalsIgnoreCase("ABCDE"); // b2 = true
boolean equalsIgnoreCase(String str)
- 문자열(str)과 String 인스턴스의 문자열을 대소문자 구분 없이 비교
- 내용이 같으면 true, 다르면 false 반환
String s = "Hello";
int i1 = s.indexOf('o'); // i1 = 4
int i2 = s.indexOf('a'); // i2 = -1
int indexOf(int ch)
- 주어진 문자(ch)가 문자열에 존재하는지 확인
- 존재한다면 해당 문자의 위치(index)를 반환
- 존재하지 않는다면 -1 반환
String s = "Hello";
int i1 = s.indexOf('e', 0); // i1 = 1
int i2 = s.indexOf('e', 3); // i2 = -1
int indexOf(int ch, int pos)
- 주어진 문자(ch)가 문자열에 존재하는지 지정된 위치(pos)부터 확인
- 존재한다면 해당 문자의 위치(index)를 반환
- 존재하지 않는다면 -1 반환
String s = "abcde";
int i = s.indexOf("cd"); // i = 2
int indexOf(String str)
- 주어진 문자열(str)이 문자열에 존재하는지 확인
- 존재한다면 해당 문자열의 시작 위치(index)를 반환
- 존재하지 않는다면 -1 반환
String s = "Hello";
int i1 = s.indexOf('l'); // i1 = 2
int i2 = s.lastIndexOf('l'); // i2 = 3
int lastIndexOf(int ch)
- 지정된 문자(ch)를 문자열의 오른쪽 끝(뒤쪽)에서부터 찾음
- 존재한다면 해당 문자의 위치(index)를 반환
- 존재하지 않는다면 -1 반환
String s = "Hello mom! Hello Dad!";
int i1 = s.indexOf("Hello"); // i1 = 0
int i2 = s.lastIndexOf("Hello"); // i2 = 11
int lastIndexOf(String str)
- 지정된 문자열(str)을 문자열의 오른쪽 끝(뒤쪽)에서부터 찾음
- 존재한다면 해당 문자열의 시작 위치(index)를 반환
- 존재하지 않는다면 -1 반환
String s = "Hello";
int len = s.length(); // len = 5
int length()
- 문자열의 길이 반환
String animals = "dog,cat,bear";
String[] arr = animals.split(",");
// arr[0] = "dog"
// arr[1] = "cat"
// arr[2] = "bear"
String[] split(String regex)
- 문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환
- regex = regular expression, 정규 표현식
String animals = "dog,cat,bear";
String[] arr = animals.split(",", 2);
// arr[0] = "dog"
// arr[1] = "cat,bear"
String[] split(String regex, int limit)
- 문자열을 지정된 분리자(regex)로 나누어 문자열 배열에 담아 반환
- 문자열 전체를 지정된 수(limit)로 자르기 때문에 문자열 배열의 길이가 limit과 같아짐
String s = "abcde";
boolean b1 = s.startsWith("ab"); // b1 = true
boolean b2 = s.startsWith("abd"); // b2 = false
boolean startsWith(String prefix)
- 주어진 문자열(prefix)로 시작하는지 확인
- 맞으면 true, 아니면 false 반환
- endsWith 메서드와 반대
String s = "abcdefg";
String s1 = s.substring(3); // s1 = "defg"
String s2 = s.substring(1,5); // s2 = "bcde"
String substring(int begin) // String substring(int begin, int end)
- 주어진 시작 위치(begin) 이상 끝 위치(end) 미만의 범위에 있는 문자열을 반환
- end를 지정하지 않으면 문자열 길이로 자동 인식
String s = "Hello";
String ss = s.toLowerCase(); // ss = "hello"
String toLowerCase()
- 모든 문자열을 소문자로 변환
String s = "Hello";
String ss = s.toUpperCase(); // ss = "HELLO"
String toUpperCase()
- 모든 문자열을 대문자로 변환
String s = " H e l l o ";
String ss = s.trim(); // ss = "H e l l o"
String trim()
- 문자열 양 끝의 공백을 없앤 결과 반환
- 문자열 중간의 공백은 제거되지 않음
String b1 = true + ""; // b1 = "true"
String b2 = String.valueOf(true); // b2 = "true"
String c = String.valueOf('a'); // c = "a"
String i = String.valueOf(10); // i = "10"
String l = String.valueOf(10L); // l = "10"
String f = String.valueOf(10f); // f = "10.0"
String d = String.valueOf(10.0); // d = "10.0"
java.util.Date dd = new java.util.Date();
String date = String.valueOf(dd); // date = "Tue Aug 16 23:30:39 KST 2022"
static String valueOf(types x)
- types: boolean, char, int, long, float, double, Object
- x의 값을 문자열로 변환 후 반환
- 참조변수의 경우 toString()을 호출한 결과를 문자열로 반환
- b1처럼 빈 문자열을 더해서 문자열로 변환할 수 있지만, valueOf 메서드를 이용하는 것이 속도가 더 빠름
[쿠키글] CharSequence 인터페이스
char[]을 다루는 클래스는 총 5가지가 있다.
- CharBuffer - Segment - String - StringBuffer - StringBuilder
이 클래스들은 공통 조상이 없어서, 인터페이스인 CharSequence를 구현하게 함으로써 다형성을 만들어줬다.
'Java' 카테고리의 다른 글
StringBuffer 클래스 (0) | 2022.08.18 |
---|---|
문자열의 결합과 변환 (0) | 2022.08.18 |
Object 클래스와 메서드 (0) | 2022.06.16 |
연결된 예외 (0) | 2022.06.10 |
사용자 정의 예외 만들기, 예외 되던지기 (0) | 2022.05.27 |