일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 병행성 관련 오류
- I/O장치
- 프로그래머스
- 컨디션 변수
- 렌더링 파이프라인
- DirectX 12
- directx
- 동적계획법
- 그리디알고리즘
- 자료구조
- 멀티쓰레드
- codility
- 멀티프로세서
- 다이나믹프로그래밍
- 파일시스템 구현
- 그리디 알고리즘
- 운영체제
- 타입 객체
- 백준
- 알고리즘
- 병행성
- 영속성
- 다이나믹 프로그래밍
- 스케줄링
- 락
- 디자인패턴
- 쓰레드
- OS
- DirectX12
- Direct12
- Today
- Total
기록공간
Java의 주요 클래스(2) 본문
String 클래스
String 클래스는 내부 문자열에 대한 수정이 불가능하다. (내용 불변 : Immutable) 문자열의 내용이 변경되면 새로운 객체를 생성하며 참조 대상을 잃어버린 객체는 가비지 컬렉션의 대상이 되고, 새로운 객체에 새 주소를 할당하게 되므로 해시코드도 변하게 된다.
String 클래스 간에 + 연산자를 사용하게 되면 문자열 간의 결합이 가능하며, String 클래스와 다른 클래스 객체, 또는 기본형 데이터 간에 + 연산자를 사용하는 경우에도 내부적으로 자동 String 클래스로 변환이 가능하다.
String은 내부 문자열의 내용을 변경할 수 없기 때문에 + 연산자를 사용하여 문자열의 결합을 수행하게 되면 내부적으로 StringBuffer를 생성하여 append() 메서드를 이용해 문자열에 대한 결합을 수행하게 된다.
따라서, 동적인 문자열을 많이 사용하는 Servlet 등에서는 되도록이면 String을 사용하는 것 보다 StringBuffer나 char[] 을 사용하는 것이 효율적일 수 있다.
=> 정적인 문자열을 처리하는 경우 주로 String 클래스를 사용
=> 동적인 문자열을 처리하는 경우 런타임시 동적으로 처리해주는 StringBuffer 클래스를 사용하는 것이 효율적이다.
String 객체의 생성 및 특징
String 객체를 생성하는 방법은 두 가지가 있다.
//1) 문자열 상수를 지정하는 방법
String str1 = "Java";
//2) String 클래스의 생성자를 이용하는 방법
String str2 = new String("Java");
첫 번째 방법을 사용하여 객체를 생성하는 경우와 두 번째 방법을 사용하여 객체를 생성하는 것은 처리 과정과 의미가 다르다.
String s1 = "seoul";
String s2 = "seoul";
String s3 = new String("seoul");
String s4 = new String("seoul");
String 객체에 담기는 정보는 그저 해당하는 문자열을 가리키는 주소일 뿐이다. 문자열 자체를 의미하는 것이 아니라는 점을 주의해야 한다. 위 코드에서 "seoul" 상수 리터럴 문자열은 이미 컴파일 시점에서 메모리에 퍼올려진다. 그리고 s1과 s2는 서로 같은 메모리 주소를 가리키고 있다. 때문에 s1과 s2를 비교해보면 같다고 나온다. (s1 == s2)
하지만 new String("seoul") 같은 경우에는 메모리에 "seoul"이 있든 없든 무조건 메모리에 퍼올려진다. 때문에 s3과 s4는 새로운 메모리를 가리키고 있기 때문에 서로 다르다. (s3 != s4)
때문에 문자열 자체를 비교하고 싶으면 String 클래스 메서드인 equals() 를 사용해야 한다. (equalsIgnoreCase()를 사용하는 경우 대소문자 구분 없이 문자열을 비교해준다)
String s1 = "seoul";
String s2 = "seoul";
String s3 = new String("seoul");
String s4 = new String("seoul");
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 s = "seoul korea";
System.out.println(s.equalsIgnoreCase("Seoul Korea"));
//--==>> true
String 객체는 기존 클래스 객체들과 다르게 인스턴스 명을 출력하는 경우 그 객체가 가리키고 있는 문자열을 출력한다. 만약 해시코드를 출력해야 한다면 hashCode() 메서드를 호출하면 된다. 하지만 해시코드가 같다고 해서 같은 객체는 아니라는 것에 유의해야 한다.
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
substring() 메서드
substring() 메서드는 String 객체 문자열을 대상으로 (substring(int s, int e)) s 번째에서 e - 1 번째 까지의 문자열을 추출해준다.
String s = "seoul korea";
System.out.println(s);
// --==>> seoul korea
// 문자열 추출
System.out.println(s.substring(6, 9));
// --==>> kor
만약 substring(int s) 이렇게 사용할 경우 s 번째에서 끝까지 (문자열이 가진 길이만큼) 문자열을 추출해준다.
String s = "seoul korea";
System.out.println(s);
// --==>> seoul korea
System.out.println(s.substring(7));
// --==>> orea
indexOf() 메서드
indexOf() 메서드는 (indexOf(String s)) 찾고자 하는 대상 문자열에 s 문자열이 존재 하는 경우 그것에 시작 위치를 반환해준다. 만약 s 문자열을 찾지 못했다면 -1을 반환한다.
(만약 뒤에서 부터 검사하고 싶은 경우에는 lastIndexOf() 메서드를 사용할 수도 있다)
String s = "seoul korea";
System.out.println(s);
// --==>> seoul korea
System.out.println(s.indexOf("kor"));
//--==>> 6
System.out.println(s.indexOf("ea"));
//--==>> 9
System.out.println(s.indexOf("e"));
//--==>> 1
System.out.println(s.indexOf("tt"));
//--==>> -1
System.out.println(s.lastIndexOf("e"));
//--==>> 9
System.out.println(s.lastIndexOf("o"));
//--==>> 7
endsWith() 메서드
endsWith() 메서드는 (endsWith(String s)) 대상 문자열에 s 문자열로 끝나는지에 대한 여부를 확인해준다. 만약 s로 끝난다면 true를 아니라면 false를 반환한다.
String s = "seoul korea";
System.out.println(s.endsWith("rea"));
//--==>> true
System.out.println(s.endsWith("oul"));
//--==>> false
charAt() 메서드
charAt() 메서드는 (charAt(int idx)) idx 번째 인덱스 위치의 문자가 무엇인지 알려주는 함수이다. 호출하면 해당 객체 문자열의 idx 번째 문자를 반환한다.
// seoul korea
System.out.println(s.charAt(6));
//--==>> k
만약 idx가 문자열 범위를 넘어간다면 StringIndexOutOfBoundsException 런타임 에러가 발생하기 때문에 이를 주의하면서 사용해야 한다. (혹은 예외처리를 해주거나)
compareTo() 메서드
compareTo() 메서드는 (compareTo(String s)) 해당 객체 문자열과 s를 비교하여 어떤 문자열이 얼마나 더 큰지를 알려주는 함수이다. 서로의 차이 값은 사전식 배열을 기준으로 처리한다. 만약 객체 문자열의 3번째 문자가 c이고 s 문자열 3번째 문자가 k이면, 3번째 문자만 차이가 있는 경우 compare() 값은 'k' - 'c' = 8 이 된다.
// seoul korea
System.out.println(s.compareTo("seoul korea"));
//--==>> 0
System.out.println(s.compareTo("seoul corea"));
//--==>> 8
replaceAll(), replace() 메서드
replaceAll() 메서드는 (replaceAll(String a, String b), replace(String a, String b)) 해당 객체 문자열에서 a가 들어간 문자열을 b로 바꿔준다. replaceAll과 replace의 차이점은 정규식을 사용할 수 있는가 없는가에 있다.
s = "우리나라 대한민국 대한독립 만세";
s = s.replaceAll("대한", "자주");
System.out.println(s);
//--==>> 우리나라 자주민국 자주독립 만세
s = "abcabcabcaaabcd";
s = s.replace("abc", "T");
System.out.println(s);
//--==>> TTTaaTd
s = "abcabcabcaaabcd";
System.out.println(s.replace("abc", "T"));
System.out.println(s.replaceAll("[abc]", "T"));
//--==>> TTTaaTd
// TTTTTTTTTTTTTTd
공백 제거
문자열에서 공백을 제거 하는 방법은 두 가지가 있고 처리 방식도 조금씩 다르다. 첫 번째 방법은 trim() 메서드를 이용하는 것이다. 하지만 이 방법은 사이에 있는 공백은 제거할 수 없다. 이를 해결한 방법이 두 번째 방법인 replaceAll(" ", "")이다.
s = " 사 랑 ";
System.out.println("|" + s + "|");
//--==>> | 사 랑 |
System.out.println("|" + s.trim() + "|");
//--==>> |사 랑|
System.out.println("|" + s.replaceAll(" ", "") + "|");
//--==>> |사랑|
format() 메서드
format() 메서드는 (format(서식, 서식에 알맞는 값)) 서식에 맞게 문자열로 만들어 반환시켜준다. format()은 스태틱 메서드로 객체 생성 없이 바로 사용이 가능하다는 특징이 있다.
s = String.format("%d", n);
System.out.println(s);
//--==>> 2345678
System.out.format("%.2f", 3.141592);
System.out.println();
s = String.format("%.2f", 3.141592);
//"3.14";
System.out.println(s);
//--==>> 3.14
split() 메서드
split() 메서드는 (split(String s)) 해당 객체 문자열을 s를 기준으로 분리해주는 작업을 수행한다. 자른 문자열들을 담은 문자열 배열 형태로 반환된다.
String[] strArr = "기본,열정,배려".split(",");
for (String str : strArr)
{
System.out.print(str + " ");
}
System.out.println();
//--==>> 기본 열정 배려
StringBuffer 클래스
StringBuffer 클래스는 문자열을 처리하는 클래스이다. String 클래스와의 차이점은 String 클래스는 내부 문자열 데이터의 수정이 불가능하지만 StringBuffer 클래스는 문자열을 사용할 때 내부 문자열을 실행 단계에서 변경할 수 있다는 것이다. StringBuffer 클래스는 내부에 버퍼 메모리를 따로 잡고 있기 때문에 이러한 기능을 수행할 수 있다.
StringBuffer 객체는 가변적인 길이를 가지므로 객체를 생성하는 시점에서 미리 그 크기가 값을 지정하거나 실행 시점에 버퍼의 크기를 바꿀 수 있는 기능을 제공한다.
또한 JDK 1.5 이후부터는 문자열을 처리하는 StringBuilder라는 클래스도 제공한다. StringBuilder 클래스의 기능은 StringBuffer 클래스와 동일하지만 가장 큰 차이점은 멀티스레드에 안전하지 않다(unsfae)는 점이다. 즉, 동기화(Syncronization)가 없기 때문에 StringBuffer보다 빠르며 동시성 문제가 없다면 StringBuilder를 사용하는 것이 성능을 향상시킬 수 있다. (동기화 작업을 배제하고 들어가기 때문에)
equals() 메서드
StringBuffer sb1 = new StringBuffer("korea");
StringBuffer sb2 = new StringBuffer("korea");
System.out.println(sb1 == sb2);
System.out.println(sb1.equals(sb2));
//--==>> false
// false
String 클래스의 equals() 메서드와 다르게 동일한 문자열이여도 false를 반환하였다. 이를 통해 StringBuffer는 equals() 메서드를 오버 라이딩하지 않았다는 것을 알 수 있다. 즉, StringBuffer의 최상위 부모인 java.lang.Object 클래스의 equals() 메서드를 사용하고 있기 때문에 서로가 가리키고 있는 문자열 주소 값을 통해 비교한다.
따라서 String의 equals() 메서드를 사용하고 싶다면 StringBuffer 인스턴스를 toString() 메서드를 이용해 String 클래스 형식으로 변환 후 사용해야 한다.
capacity() 메서드
StringBuffer sb3 = new StringBuffer();
System.out.println("버퍼 크기 : " + sb3.capacity());
//--==>> 버퍼 크기 : 16
capacity() 메서드를 사용하면 현재 StringBuffer 인스턴스에 할당된 문자열 버퍼 크기가 몇인지 알 수 있다. 버퍼 크기는 문자열이 추가되는 경우 자동으로 크기가 늘어나지만 자동으로 줄여주는 것은 지원하지 않는다.
append() 메서드
sb3.append("seoul"); // sb3 += "seoul";
sb3.append("korea");
sb3.append("우리나라");
sb3.append("대한민국");
System.out.println(sb3);
System.out.println(sb3.toString());
//--==>> seoulkorea우리나라대한민국
// seoulkorea우리나라대한민국
StringBuffer 클래스는 String과 다르게 + 연산을 지원하지 않는다. 그렇기 때문에 문자열을 서로 합치는 작업을 하고 싶은 경우 append() 메서드를 사용해야 한다.
toUpperCase(), toLowerCase() 메서드
String temp3 = sb3.toString();
System.out.println(temp3.toUpperCase());
//--==>> SEOULKOREA우리나라대한민국
System.out.println(sb3.toString());
//--==>> seoulkorea우리나라대한민국
toUpperCase() 메서드는 문자열에 존재한 모든 알파벳 문자를 대문자로, toLowerCase() 메서드는 소문자로 바꿔준다.
insert() 메서드
// ○ 대상 문자열(sb3) 중 seoul 앞에
// ["한국"] 이라는 문자열 추가
sb3.insert(0, "한국");
System.out.println("seoul 앞에 [한국] 추가 : " + sb3.toString());
//--==>> seoul 앞에 [한국] 추가 : 한국seoulkorea우리나라대한민국
insert() 메서드는 (insert(int idx, String s)) 해당 idx 위치에 s 문자열을 추가해주는 기능을 한다.
delete() 메서드
// ○ 대상 문자열(sb3)에서
// [우리나라] 문자열 삭제
// 한국seoulkorea사랑우리나라대한민국
sb3.delete(14, 18);
System.out.println(sb3);
//--==>> 한국seoulkorea사랑대한민국
delete() 메서드는 (delete(int idx_start, int idx_end)) idx_start 위치의 문자부터 idx_end 문자 바로 전까지의 모든 문자를 삭제한다.
StringTokenizer 클래스
StringTokenizer 클래스는 문자열 파싱(parsing)을 제공하는 클래스로 파싱하고자 하는 문자열을 인자로 받아 생성하는데, 여기서 파싱이란 하나의 문자열을 여러 문자열로 나누는 작업을 의미하게 되며, 이때 나누는 단위가 되는 문자열을 토큰(token)이라고 한다.
StringTokenizer 클래스는 호환성을 유지하는 목적으로 보관 유지되고 있으며, 문자열을 파싱하기 위해서는 String 클래스의 split() 메서드나 java.util.regax 패키지를 사용할 것을 권장하고 있다.
예제)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Test145
{
public static void main(String[] args) throws IOException
{
String strTemp;
String[] strArr;
int n;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("파싱할 문자열 입력(컴마구분) : ");
strTemp = br.readLine();
// 테스트(확인)
//System.out.println(strTemp);
//--==>> 사과,딸기,바나나
// StringTokenizer 클래스 인스턴스 생성
StringTokenizer st = new StringTokenizer(strTemp, ",");
//-- strTemp 를 대상 문자열로...
// [,]를 구분자로...
strArr = new String[st.countTokens()];
// [int countTokens()]
// : 파싱된 문자열의 갯수를 리턴(반환)한다.
//-- [String[] strArr = new String[3];] 와 동일한 구문
n = 0;
while(st.hasMoreTokens()) // 다음값 있는지 망보는 작업 (true, false)
{
strArr[n++] = st.nextToken();
}
// [hasMoreTokens()]
// : 사용할 수 있는 토큰이 남아있는 경우 true를 반환.
// 더 이상 사용할 토큰이 남아있지 않은 경우 false를 반환.
// 확인 결과에 대한 반환만 할 뿐...
// 실제 내용을 읽어들이는 헤드를 이동시키지 않는다.
// [nextToken()]
// : 다음 토큰을 얻어온다.
// 다음 토큰을 얻어오며 헤드를 이동시키게 된다.
// 구분자를 바꾸었을 경우 다음 호출에도
// 바뀐 구분자를 이용하여 토큰을 분리한다.
System.out.println();
System.out.print("파싱된 토큰(문자열) : ");
for(String str : strArr)
System.out.print(str + " ");
System.out.println();
}
}
'Java' 카테고리의 다른 글
Java의 주요 클래스(3) (0) | 2020.09.01 |
---|---|
문자 집합 (Character Set) (0) | 2020.08.31 |
Java의 주요 클래스(1) (0) | 2020.08.26 |
클래스 고급 - 중첩 클래스(내부 클래스) (0) | 2020.08.25 |
클래스 고급 - 인터페이스(Interface) (0) | 2020.08.25 |