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의 차이를 알아두는 것이 좋을 것 같다.