Java

String 클래스

jamie. 2020. 1. 6. 21:45
반응형

특징

immutable한 Object

- immutable : 불변의

- 한 번 생성되면 더 이상 그 값을 변경할 수 없음

즉, String 문자열을 더할 경우 새로운 String 객체가 생성되고 기존 객체는 버려짐

- 기존 객체는 버려지며, 나중에 GC(Garbage collection)의 대상이 됨

자주 쓰이는 생성자

String Object는 대부분 ""로 생성하기 때문에 굳이 생성자를 사용하지는 않음

아래 생성자들은 한글을 사용하는 우리나라에서 자주 사용하는 생성자

// 현재 사용중인 플랫폼의 charset을 이용하여 제공된 byte array를 decoding한 String Object 생성
String(byte[] bytes)
// 지정한 charset을 이용하여 제공된 byte array를 decoding한 String Object 생성
String(byte[] bytes, String charsetName)

String을 byte Array로 변환

// Default CharSet의 byte Array를 생성
byte[] getBytes()
// 지정한 Charset Type으로 Byte Array 생성
byte[] getBytes(Charset charset)
// 지정한 이름의 Charset을 갖는 Byte Array 생성
byte[] getBytes(String charset)

java.nio.Charset 클래스 API - Standard charsets

US-ASCII Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
ISO-8859-1   ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
UTF-8 Eight-bit UCS Transformation Format
UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order
UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order
UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark

객체의 Null 체크

Object==Null && Object!=Null

길이 확인

int length()

jamieStr.length();

비어있는지 확인

boolean isEmpty();

jamieStr.length()==0;
jamieStr.isEmpty(); // 간단

같은지 비교

boolean equals(Object anObject)
boolean equalsIgnoreCase(String anotherStr) // 대소문자 구분 X

/* sorting시 주로 사용
 * 비교하려는 매개 변수가 알파벳 순으로 앞이라면 양수, 뒤라면 음수 리턴
 * 알파벳 순서만큼 숫자값 증가
 */
int compareTo(String anotherStr)
int compareToIgnoreCase(String str)	// 대소문자 구분 X

// CharSequence or StringBuffer 객체와 String 비교
boolean contentEqauls(CharSequence cs)
boolean contentEqauls(SpringBuffer sb)

위치 찾기

// 왼쪽부터 검사
int indexOf(int ch)
int indexOf(int ch, int fromIndex)
int indexOf(String str)
int indexOf(String str, int fromIndex)

// 오른쪽부터 검사
int lastIndexOf(int ch)
int lastIndexOf(int ch, int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)

/* Java Index는 0부터 시작함, FromIndex = 몇 번째부터 검사할지
 * 포함되어 있지 않다면 둘 다 -1을 리턴
 */

특정 조건에 맞는 문자열이 있는지 확인

// 매개 변수 값으로 시작하는지 검증
boolean startsWith(String prefix)
boolean startsWith(String prefix, int toffset)

// 매개 변수 값으로 끝나는지 검증
boolean endsWith(String suffix)

// 매개 변수 값이 문자열에 존재하는지 확인
boolean contains(CharSequence s)

// 매개 변수 정규식이 문자열에 매칭되는지 확인
boolean matches(String regex)

/* 특정 영역이 매개 변수로 넘어온 문자열과 동일한지 확인
 * ignoreCase : true인 경우 대소문자 구분을 하지 않고 값을 비교
 * toffset : 비교 대상 문자열의 확인 시작 위치 지정, 음수면 false, toffset+len > 비교대상이면 false
 * other : 존재하는지 확인할 문자열
 * ooffset : other 객체의 확인 시작 위치를 지정, 음수면 false, ooffset+len > other이면 false
 * len : 비교할 char의 개수를 지정
 */
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
boolean regionMatches(int toffset, String other, int ooffset, int len)

일부 추출

char

// 특정 위치의 char 값 리턴
char charAt(int index)

// 지정된 index부터 offset이 설정된 index를 리턴 - 문자열 인코딩과 관련된 문제를 해결하기 위해 사용
int offsetByCodePoints(int index, int codePointOffset)

char Array → String

// char 배열을 문자 값으로 변환
static String copyValueOf(char[] data)

// char 배열을 문자 값으로 변환, 단 offset ~ count까지의 개수만큼
static String copyValueOf(Char[] data, int offset, int count)

String → Char Array

// 문자열을 char 배열로 변환
char[] toCharArray()

String 일부 자르기

// beginIndex ~ 끝까지 String을 잘라 String으로 리턴
String substring(int beginIndex)

/* beginIndex ~ endIndex까지 String을 잘라 String으로 리턴
 * 단, endIndex >= beginIndex
 * 그렇지 않으면 StringIndexOutOfBoundsException 발생
 */
String substring(int beginIndex, int endIndex)

// beginIndex ~ endIndex까지 String을 잘라 CharSequence 타입으로 리턴
CharSequence subSequence(int beginIndex, int endInex)

String을 여러 개의 String Array로 나누기

// regex에 있는 정규 표현식에 맞추어 String을 잘라 String Array로 리턴
String[] split(String regex)

// regex에 있는 정규 표현식에 맞추어 String Array로 리턴, 단 limit보다 배열의 크기가 클 수 없음
String[] split(String regex, int limit)

/* 정규식을 사용하지 않고 특정 String으로 나눈다면 StringTokenizer 클래스를 사용하는 것이 편함
 * 특정 알파벳이나 기호 하나로 나눈다면, split()이던 StringTokenizer던 상관 없음
 */

String 값 변경

공백 제거

// 앞 뒤의 공백을 제거한 String 리턴
String trim()

내용 대치(replace)

// oldChar의 값을 newChar로 대치
String replace(char oldChar, char newChar)

// target과 같은 값을 replacement로 대치
String replace(CharSequence target, CharSequence replacement)

// regex에 표현된 정규표현식에 포함되는 모든 내용을 replacement로 대치
String replaceAll(String regex, String replacement)

// regex에 표현된 정규표현식에 포함되는 첫번째 내용을 replacement로 대치
String replaceFirst(String regex, String replacement)

형식에 맞춰 값을 치환

// format 중 변환해야 하는 부분을 args로 변환
static String format(String format, Object... args)

// 출력만 하려면 아래 메서드 이용해도 상관 없음
System.out.format()

/* 매개 변수 수 < 변경해야 할 대상 수
 * java.util.MissingFormatArgumentException
 */

대소문자 변경

// 소문자로
String toLowerCase()
// 대문자로
String toUpperCase()

자료형을 String으로 변환

static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(char[] data)
static String valueOf(char[] data, int offset, int count)
static String valueOf(double d)
static String valueOf(float f)
static String valueOf(int i)
static String valueOf(long l)
// 객체가 null이라면 "null"이라는 String을 리턴함
static String valueOf(Object obj)

/* +"" vs valueOf
 * 아래 두 개는 결과는 같지만, 별도의 문자열과 합치는 과정이 없을 경우엔 valueOf 사용 권장
 */
String.valueOf(jamieStr);
jamieStr+"";

주의, 사용하지 말 것 - intern()

C로 구현되어 있는 native 메서드 중 하나

시스템의 심각한 성능 저하를 발생시킬 수도 있음

- 억지로 Constant pool에 값을 할당하도록 만드므로, 저장되는 영역은 한계가 있으므로 그 영역에 대해서 메모리를 지우는 단계를 거치게 됨

- equlals() 보다 ==이 빠르지만, 이 작은 차이를 위해서 intern()을 사용하기엔 매우 비생산적

// Constant pool에 해당 값이 없으므로 새로 생성
String jamieStr1 = "Jamie";

// 같은 문자열이 Constant pool에 있으므로 해당 값을 사용
String jamieStr2 = "Jamie";
// 즉 jamieStr1==jamieStr2
System.out.println(jamieStr1==jamieStr2); // true

// 같은 문자열이 있건 말건 새로운 객체 생성
String jamieStr3 = new String("Jamie");
// 즉 jamieStr1!=jamieStr3
System.out.println(jamieStr1==jamieStr3); // false

// 같은 문자열이 있건 말건 새로운 객체 생성
String jamieStr4 = new String("Jamie");
/* intern()은 풀에 해당 값이 있으면, 풀에 있는 값을 리턴, 없다면 풀에 해당 값을 추가 
 * 성능에 악영향을 끼치는 부분
 */
jamieStr4 = jamieStr4.intern();
// 즉 jamieStr1==jamieStr4
System.out.println(jamieStr1==jamieStr4); // true

StringBuffer와 StringBuilder 

immutable한 String의 단점을 보완하기에 나온 클래스

- 문자열을 더하더라도 새로운 객체를 생성하지 않음

append() 메서드

매개 변수로 모든 기본 자료형과 참조 자료형 사용 가능

StringBuilder jamieSb = new StringBuidler();
jamieSb.append("Hello");
jamieSb.append(" world");
jamieSb.append(" Hello").append(" world");

특징

JDK 5 ~ String의 더하기 연산시, 컴파일할 때 자동으로 해당 연산은 StringBuilder로 변환해줌

- 일일이 더하는 작업을 변환해줄 필요는 없음

- for 루프와 같은 반복 연산시에는 자동 변환이 안되므로 꼭 필요함

공통점

모두 문자열을 다룸

CharSequence 인터페이스를 구현

= String / StringBuffer / StringBuilder를 사용하여 매개 변수로 받는 작업을 할 때 CharSequence 타입으로 받는 것이 좋음

차이점

StringBuffer == Thread Safe (더 안전함)

- 어떤 클래스에 문자열을 생성하여 더하기 위한 문자열을 처리하기 위한 인스턴스 변수가 선언

- 어떤 쓰레드에서 해당 변수를 동시에 접근하는 경우

StringBuilder != Thread Safe (속도는 더 빠름)

- 하나의 메서드 내에서 문자열을 생성하여 더할 경우

반응형