public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
// ...
}
String
은 문자형 배열을 저장하는 클래스이며, 이를 다룰수 있는 여러 메서드들을 제공한다.
String
은 변경 불가능한 클래스이다.
String a = "A";
String b = "B";
a = a + b; //--1
이렇게 하면 A
-> AB
로 변하는 것 같지만, 실제 동작은 변경하지 않는다. --1
의 수행 과정에서, 새로운 객체 AB
라는 새로운 인스턴스가 생성되고, a
가 더이상A
가 아닌 AB
를 가리키게 되는 것이다.
String
클래스의 이러한 특성 때문에 기본형(int, double, char, ...)와 동일한 방법으로 작동하지 않는다. 보이기엔 비슷하게 작동하지만, 효율성을 높히고자 한다면 동작원리에 대해 알 필요가 있을 것이다.
String a1 = "A"; //--1
String a2 = "A";
String a3 = new String("A"); //--2
String a4 = new String("A");
--1
과 --2
의 결과는 같겠지만, --1
의 방식이 권장된다. 프로그램이 동작하면, --1
에 존재하는 A
는 constant pool
이라는 곳에 저장되고, 이를 재사용한다. 그래서 a1
과 a2
는 같은 인스턴스(?)를 가리키지만, 생성자(--2)
를 통해 생성하면, a3
와 a4
가 각각 새로운 인스턴스를 생성하기 때문에 성능면에서 조금 떨어질 수 있다.
String(String s)
String(char[] value)
: char의 배열을 String으로 만듦
char[] ab = {'A','B'};
String s = new String(ab); //AB
String(StringBuffer value)
: StringBuffer를 String으로 만듦
int compareTo(String str)
: str
과 사전순서로 비교하여 결과 반환, 정렬때 유용할 듯
int i = "a".compareTo("b"); // -1 a < b
int i = "b".compareTo("a"); // 1 b > a
int i = "aa".compareTo("aa"); // 0 aa == aa
boolean equals(Object obj)
: 일치하는지 비교
String a = "A";
boolean same = a.equals("A"); //true
boolean diff = a.equals("a"); //false
//대소문자 구분 없이 비교할 경우
boolean ignoreCase a.equalsIgnoreCase("a"); //true
boolean contains(CharSequence s)
: s
를 포함하는지 검사
String a = "ABC";
boolean b = a.contains("AB"); //true
int indexOf(int ch)
: ch
의 위치를 반환
String a = "HelloolleH";
int h1 = a.indexOf("H"); // 0, 맨 앞에서부터 찾음
int h2 = a.indexOf("H", 3); // 9, 3의 위치부터 찾음
int none = a.indexOf("K"); // -1, 없으면 -1
int s1 = a.indexOf("ll"); // 3
int h3 = a.lastIndexOf("H");// 9, 뒤에서부터 찾아서 위치 반환
char loc = a.charAt(9); //H, 9에 있는 문자를 반환
boolean startsWith(String str)
: str
로 시작하는지 확인
String a = "HelloWorld";
boolean starts = a.startWith("Hel"); // true
boolean ends = a.endsWith("ld"); //true 끝나는 문자 확인
int length()
: 길이 반환
String substring(int begin)
: begin
부터 나눈 문자열 반환
String a = "HelloWorld !!!";
String b = a.substring(5); //World !!!
String c = a.substring(0,5); //Hello 0~4까지
String trim()
: 양옆 공백 제거
String a = " Hello ab ";
String b = a.trim(); //Hello ab
String[] split(String regex)
: regex
로 나누어 문자열 배열로 담기
String a = "A,B,C";
String[] aArr = a.split(",");
//aArr[0] = A
//aArr[1] = B
//aArr[2] = C
//join을 통해 결합하여 문자열로 만들 수 있다
String aAgain1 = String.join(",", aArr);
// A,B,C
String aAgain2 = String.join("-", aArr);
// A-B-C
String concat(String str)
: str
을 붙히기
String a = "A";
String b = "B";
String ab = a.concat(b); //AB
String toLowerCase()
: 소문자로,
String toUpperCase()
: 대문자로
String.valueOf()
를 통해 변환 가능public class playGround {
public static void play(){
int integer = 10;
char character = 'A';
boolean isTrue = true;
double doubleNumber = 10.12;
System.out.println(String.valueOf(integer)); //10
System.out.println(String.valueOf(character)); //A
System.out.println(String.valueOf(isTrue).toUpperCase()); //TRUE
System.out.println(String.valueOf(doubleNumber)); // 10.12
String a = number + "";
String b = String.valueof("10");
//동일한 결과지만, valueOf의 성능이 더 우세함
}
}
반대의 경우도 valueOf()
를 사용하지만, 변환하려는 타입에 맞는 래퍼클래스를 통해 사용해야한다.
public class playGround {
public static void play(){
String number = "10";
String doubleNumber = "10.12";
System.out.println(Integer.valueOf(number) + Double.valueOf(doubleNumber)); //20.119999999999997
//int와 double의 연산
int a = number + "";
int b = Integer.valueof("10");
}
}
String
클래스와 유사하게 문자열을 저장할 수 있지만, 변경에 용이한 클래스이다.
char[]
를 좀더 유연하게 사용하여 문자 편집에 용이하다. 기본적인 크기(16)가 존재하고, 필요에 맞게 조절할 수 있다.
public class playGround {
public static void play(){
StringBuffer sb = new StringBuffer("abc"); //--1
System.out.println(sb.capacity()); //19
System.out.println(sb.length()); //3
StringBuffer sb2 = new StringBuffer(10); //--2
System.out.println(sb2.capacity()); //10
}
}
StringBuffer
인스턴스를 만들어야 한다.
이때, 문자열을 주면(--1)
예상대로 동작한다. 문자열의 길이에 추가적으로 기본크기인 16이 추가되어 문자열을 담은 char[]
의 길이가 19(16 + 3)이 된다.
(--2)
처럼 정수값을 주면, 기본값이 아닌 원하는 길이의 char[]
이 생성된다.
.capacity()
와 .length()
의 차이도 코드를 통해 확인할 수 있다.
StringBuffer append()
: 매개변수로 입력된 값을 문자열로 변환하여 맨 뒤에 추가한다
public class playGround {
public static void play(){
StringBuffer sb = new StringBuffer("abc");
sb.append(123);
sb.append(true);
System.out.println(sb); //abc123true
}
}
StringBuffer delete(int start, int end)
: start ..< end
까지의 문자를 제거한다
sb.delete(3, 6);
System.out.println(sb); //abctrue
sb.deleteCharAt(3); // 위치가 3인 문자 제거
//abcrue
StringBuffer insert(int pos, any)
: pos
위치에 any
를 삽입한다
sb.insert(3,"t");
//abctrue
StringBuffer reverse()
: 배열을 뒤집는다
sb.reverse();
//eurtcba
StringBuffer setLength
: 배열의 길이를 변경한다
public class playGround {
public static void play(){
StringBuffer sb = new StringBuffer("abcdefg");
sb.setLength(5);
System.out.println(sb); //abcde (fg는 짤림)
sb.setLength(12);
System.out.println(sb); //abcde (남은 공간은 공백으로 채워짐)
System.out.println(sb.charAt(8)); // 공백
}
}
StringBuffer
와 동일한 기능을 가진 클래스이다.
쓰레드의 동기화 유무이다. 멀티쓰레드로 작동하는 경우, 데이터들간의 동기화가 필요한데 StringBuffer
는 동기화가 자동으로 된다. 그래서 싱글쓰레드로 작동하는 프로그램의 경우에는 불필요한 성능이 될 수 있다. 큰 차이는 없을 수 있지만, 프로그램에 따라 성능향상을 고려해본다면 StringBuilder
와 StringBuffer
의 차이를 알아두는 것이 좋을 것 같다.