String 클래스
1. String 클래스는 내부 문자열 데이터에 대한 수정이 불가능하다. ★내용 불변 - Immutable★
- 문자열의 내용을 변경할 경우 기존의 객체를 내부적으로 수정하는 것이 아니라 새로운 객체를 생성하며, 참조 대상을 잃어버린 객체(기존 문자열 객체)는 가비지 컬렉션의 대상이 되고, 새로운 객체에 새 주소를 할당하게 되므로 해쉬코드도 변하게 된다.
2. String 클래스 간에 『+』연산자를 사용하게 되면 문자열 간의 결합이 가능하다.
- String 클래스와 다른 클래스 객체, 또는 기본형 데이터 간에 『+』 연산자를 사용하는 경우에도 내부적으로 자동 String 클래스로 변환이 가능하다.
"seoul" + " korea" // → "seoul korea"
"" + 100; // → "100". String 으로 변환되는 효과
※ 연산 결과를 겉으로 보기에는 문자열이 수정된 것처럼 보인다. 하지만 String은 ★내용 불변 - Immutable★
String 은 내부 문자열의 내용을 변경할 수 없기 때문에 『+』 연산자를 사용하여 문자열의 결합을 수행하게 되면 내부적으로 StringBuffer 를 생성하여 append() 메소드를 이용해 문자열에 대한 결합을 수행하게 된다.
따라서, 동적인 문자열을 많이 사용하는 Servlet 등에서는 되도록이면 String 을 사용하는 것 보다 StringBuffer 나 char[] 을 사용하는 것이 효율적일 수 있다.
* 정적인 문자열을 처리하는 경우에는 주로 String 클래스를 사용.
* 동적인 문자열을 처리하는 경우에는 런 타임 시 동적으로 처리해주는 StringBuffer 클래스를 사용하는 것이 효율적이다.
String 객체의 생성
String 객체를 생성하는 방법은
① 문자열 상수를 지정하는 방법과
② String 클래스의 생성자를 이용하는 방법
이렇게 두 가지 방법이 있다.
① String str1 = "Java";
② String str2 = new String("Java");
하지만, 『문자열 상수』를 대입 연산자를 사용하여 지정하는 방법을 통해 객체를 생성하는 경우와 『new』 연산자를 이용하여 객체를 생성하는 것은 처리 과정과 의미가 다르다(예제 코드 1 확인).
String 클래스 예제 코드 1 - String 객체의 생성, String 의 비교(==연산자, equals() 메소드), hashcode
/*=====================================
■■■ 자바의 주요(중요)클래스 ■■■
- String 클래스
=====================================*/
public class Test141
{
public static void main(String[] args)
{
String s1 = "seoul";
String s2 = "seoul";
String s3 = new String("seoul");
String s4 = new String("seoul");
//-- s1 과 s2 객체가 참조하는 '문자열 상수'가 동일한 경우
// 문자열이 저장된 기억장소의 영역이 동일하기 때문에
// s1 객체와 s2 객체는 동일한 기억 장소를 참조하게 된다.(같은 메모리 가리킴)
// 하지만, s3 와 s4 객체는 동일한 영역이 아닌 다른 기억 공간을
// 새롭게(new) 확보하여 문자열 상수를 그 공간에 대입한 상황이기 때문에
// 두 인스턴스는 같은 영역을 참조하는 것이 아니다.
// 따라서 『s3 == s4』 는 거짓이 되며(주소값 비교),
// 만약 같은 문자열 상수인지의 여부를비교해야 하는 상황이라면
// 『equals()』 메소드를 이용해야 한다.
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s4);
//--==>> true
// false
// false
System.out.println(s1.equals(s2));
System.out.println(s2.equals(s3));
System.out.println(s3.equals(s4));
System.out.println(s4.equals(s1));
//--==>> true
// true
// true
// true
// String 클래스가 Object 의 equals() 를 Overriding(재정의) 했다.
// Object 의 equals() 는 '주소값'이 같은 지 비교했지만
// String 의 equals() 는 '문자열 리터럴(상수)'가 같은 지 비교한다.
System.out.println("s1 : " + s1);
System.out.println("s2 : " + s2);
System.out.println("s3 : " + s3);
System.out.println("s4 : " + s4);
//--==>> s1 : seoul
// s2 : seoul
// s3 : seoul
// s4 : seoul
System.out.println("s1 : " + s1.hashCode());
System.out.println("s2 : " + s2.hashCode());
System.out.println("s3 : " + s3.hashCode());
System.out.println("s4 : " + s4.hashCode());
//--==>> s1 : 109324212
// s2 : 109324212
// s3 : 109324212
// s4 : 109324212
// ※ 객체가 같으면 hashCode 가 같지만 hashCode 가 같다고 해서 같은 객체는 아니다.
s2 += " korea"; // 문자열의 += 연산
System.out.println(s2);
//--==>> seoul korea
// s2 가 참조하던 "seoul"(문자열 상수)이 저장된 메모리는
// 『s2 += " korea";』 가 수행되는 시점에서 가비지 컬렉션의 대상이 되며
// "seoul korea" 문자열 상수가 저장된 영역을 s2가 새로 참조하게 된다.
s2 = "korea"; // 문자열 변경
System.out.println(s2);
//--==>> korea
// s2 가 참조한 "seoul korea" 가 저장된 메모리는
// 『s2 = "korea";』 가 수행되는 시점에서 가비지 컬렉션의 대상이 되며
// "korea" 문자열 상수가 새롭게 저장된 메모리를 s2 가 참조하게 된다.
//==> ※ String 객체의 내용은 불변이다~!!!
// 눈에는 String의 내용이 변하는 것처럼 보여도
// 실제로는 다른 내용의 문자열 상수를 참조하는 것.
s2 += 20;
System.out.println(s2);
//--==>> korea20
}
}
String 클래스 예제 코드 2 - String 클래스의 여러가지 메소드
먼저 예제 코드에서 다룰 String 클래스의 주요 메소드를 설명한다.
(자바 이후에 공부할 데이터베이스에서도 문자열 추출, 공백 제거 등을 사용하는데 용어가 다르니 이번에 제대로 봐두자)
반환형 |
메소드이름(매개변수) |
설명 |
String |
substring(int s) |
대상 문자열에서 부분 문자열 추출. String 객체의 문자열을 대상으로 s 번째부터 끝까지 (문자열의 길이만큼) 새로운 String으로 반환 |
String |
substring(int s, int e) |
대상 문자열에서 부분 문자열 추출. String 객체의 문자열을 대상으로 s 번째부터 (e-1)까지 새로운 String으로 반환 |
boolean |
equals(Object ob) |
대상 문자열과 비교 문자열의 데이터가 일치 여부 true / false 반환 |
boolean |
equalsIgnoreCase(String s) |
대상 문자열과 비교 문자열의 데이터가 일치 여부 true / false 반환 |
int |
compareTo(String s) |
대상 문자열과 비교 문자열의 데이터 크기(문자의 값)를 사전식 배열순 기준으로 비교 |
int |
indexOf(String str) |
대상 문자열에서 특정 문자열(str)의 위치 탐색 |
int |
lastIndexOf(String str) |
대상 문자열의 뒤에서부터 특정 문자열(str)의 위치를 탐색 |
boolean |
endsWith(String suffix) |
특정 문자열로 끝나는지 확인하여 true / false 반환 |
char |
charAt(int index) |
대상 문자열의 특정 위치(index)의 문자 탐색하여 문자 반환 |
String |
replaceAll(String s, String r) |
대상 문자열의 일부(s)를 다른 문자열(r)로 수정하여 문자열 반환 |
String |
replace(CharSequence t, CharSequence r) |
대상 문자열의 일부(t)를 다른 문자열(r)로 수정하여 문자열 반환 |
String |
trim() |
대상 문자열의 앞, 뒤 가장자리 공백 제거 |
String[] |
split(String regex) |
대상 문자열을 구분자(String으로 전달) 기준으로 쪼개어 각각 String으로 저장하고 그 묶음인 String 배열로 반환 |
static String |
format(String format, Object ... args) |
지정된 형식의 문자열과 인수를 전달하여 '형식이 지정된 문자열'로 변환 |
/*=====================================
■■■ 자바의 주요(중요)클래스 ■■■
- String 클래스
=====================================*/
public class Test142
{
public static void main(String[] args)
{
String s = "seoul korea";
System.out.println(s);
//--==>> seoul korea
// ○ 문자열 추출
System.out.println(s.substring(6, 9)); // 『String객체.substring(s, e)』
// String 객체 문자열을 대상으로 s 번째에서 (e-1) 번째까지 추출
// (인덱스는 0부터 시작)
//--==>> kor
System.out.println(s.substring(7)); // 『String객체.substring(s)』
// String객체 문자열을 대상으로 s 번째에서 끝까지(문자열의 길이만큼) 추출
//--==>> orea
// ○ 문자열의 데이터(값) 비교
System.out.println(s.equals("seoul korea")); // String객체.equals(s)
System.out.println(s.equals("Seoul korea"));
// Object 에 있는 equals()를 오버라이딩함. 대소문자 구분.
//--==>> true
// false
// String객체.equalsIgnoreCase(s)
System.out.println(s.equalsIgnoreCase("Seoul Korea"));
//--==>> true
//-- 대소문자 구분 안함
// ○ 대상 문자열(s)에서 특정 문자열의 위치 찾기
// s = "seoul korea"
System.out.println(s.indexOf("kor")); // String객체.indexOf(s)
//--==>> 6
System.out.println(s.indexOf("ea"));
//--==>> 9
System.out.println(s.indexOf("e"));
//--==>> 1
System.out.println(s.indexOf("tt")); // 대상 문자열에 없는 경우!
//--==>> -1
//-- 찾고자 하는 문자열이 대상 문자열에 존재할 경우
// 그 문자열의 인덱스를 반환하지만(0부터 시작)
// 존재하지 않을 경우 음수를 반환하게 된다. (-1)
// ○ 대상 문자열(s)에 특정 문자열의 위치 찾기- 문자열 뒤에서부터 검사
System.out.println(s.lastIndexOf("e")); // String객체.lastIndexOf(s)
//--==>> 9
System.out.println(s.lastIndexOf("o"));
//--==>> 7
System.out.println(s.indexOf("e")); // 참고 : 앞에서 부터 찾을 경우
//--==>> 1
System.out.println(s.indexOf("o")); // 참고 : 앞에서 부터 찾을 경우
//--==>> 2
// ○ 대상 문자열(s)이 특정 문자열 "rea"로 끝나는지의 여부 확인 (true / false)
// 메소드이름이 endsWith() 임에 주의! (endWith 아니다)
// s = "seoul korea"
System.out.println(s.endsWith("rea")); // String객체.endsWith(s)
//--==>> true
System.out.println(s.endsWith("oul"));
//--==>> false
// ○ 대상 문자열(s)의 특정 인덱스 위치의 문자
// s = seoul korea
System.out.println(s.charAt(6)); // String객체.charAt(i)
//--==>> k
//System.out.println(s.charAt(52)); // 문자열의 길이를 초과하는 index에 접근
//--==>> 에러 발생(런타임 에러)
// StringIndexOutOfBoundsException
// ○ 대상 문자열(s)과 비교 문자열의 차이를 '사전식 배열'을 기준으로 비교
// s = seoul korea
System.out.println(s.compareTo("seoul korea")); // String객체.compareTo(s)
//--==>> 0
System.out.println(s.compareTo("seoul corea"));
//--==>> 8
// c(99) d(100) e(101) f(102) g(103) h(104) i(105) j(106) k(107)
// ○ 대상 문자열(s) 중 특정 문자열을 찾아서 다른 문자열로 수정
s = "우리나라 대한민국 대한독립 만세";
s = s.replaceAll("대한", "자주"); // String객체.repleceAll(t, r)
System.out.println(s);
//--==>> 우리나라 자주민국 자주독립 만세
// replaceAll() 메소드는 정규식 사용 가능
s = "abcabcabcaaabcd";
s = s.replace("abc", "T"); // String객체.replace(t, r)
System.out.println(s);
//--==>> TTTaaTd
// replace() 메소드는 정규식 사용 불가
s = "abcabcabcaaabcd";
System.out.println(s.replace("abc", "T")); // 정규식 사용 불가
System.out.println(s.replaceAll("[abc]", "T")); // 정규식 사용. a | b | c 일때 대체
//--==>> TTTaaTd
// TTTTTTTTTTTTTTd
// ○ 공백 제거
s = " 사 랑 ";
System.out.println("[" + s + "]");
//--==>> [ 사 랑 ]
System.out.println("|" + s.trim() + "|"); // String객체.trim()
//--==>> [사 랑]
//--> 양쪽 가장자리 공백 제거(문자열 중간의 공백은 제거 불가)
System.out.println("[" + s.replaceAll(" ", "") + "]"); // replaceAll() 호출
//--==>> [사랑]
//--> 모든 공백 제거하려면 replaceAll 사용하기
// ○ 문자열을 특정 구분자 기준으로 쪼개기 - 배열로 반환
String[] strArr = "기본,열정,배려".split(","); // String객체.split(s)
for(String str : strArr)
System.out.print(str + " ");
System.out.println();
//--==>> 기본 열정 배려
// ○ 정수를 문자열로 변환
s = Integer.toString(30); // "30"
System.out.println(s);
// ○ String의 format() vs System.out.format()
int n = 2345678;
System.out.format("%d", n); // == System.out.printf("%d", n);
//--==>> 23456782345678
System.out.println();
s = String.format("%d", n); // String.format(서식, 인자) : 지정된 서식대로 문자열 변환
System.out.println(s);
//--==>> 2345678
System.out.format("%.2f", 3.141592); // 지정된 서식대로 출력
System.out.println();
//--==>> 3.14
s = String.format("%.2f", 3.141592); // 지정된 서식대로 문자열 변환
//"3.14";
System.out.println(s);
//--==>> 3.14
}
}
'자바 풀스택 과정 수업 정리 > 자바' 카테고리의 다른 글
자바 18-2 (2020.08.27) : 자바의 주요(중요) 클래스 - CharacterSet (0) | 2020.09.17 |
---|---|
자바 18-1 (2020.08.27) : 자바의 주요(중요) 클래스 - StringBuffer, StringTokenizer (0) | 2020.09.13 |
자바 17-2 (2020.08.26) : 자바의 주요(중요) 클래스 - Wrapper (0) | 2020.09.07 |
자바 17-1 (2020.08.26) : package, import, Object, 자바의 주요(중요) 클래스 - Object (0) | 2020.09.06 |
자바 16-3 (2020.08.25) : 중첩클래스(중첩 내부클래스, 내부클래스, 로컬클래스, 익명클래스) (0) | 2020.09.06 |
최근댓글