"hello"
new String("hello")
문자열은 매우 자주 사용되기 때문에, 편의상 쌍따옴표로 문자열을 감싸면 자동으로
new String
으로 변경해준다
==
equals
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("new String() == 비교: " + (str1 == str2)); // false (서로 다른 인스턴스이므로)
System.out.println("new String() equals 비교: " + (str1.equals(str2))); // true
String str3 = "hello";
String str4 = "hello";
System.out.println("리터럴 == 비교: " + (str3 == str4)); // true
System.out.println("리터럴 equals 비교: " + (str3.equals(str4))); // true
String str3 = "hello"
와 같이 문자열 리터럴을 사용하는 경우
자바는 메모리 효율성과 성능 최적화를 위해 문자열 풀
을 사용함
자바가 실행되는 시점에 클래스에 문자열 리터럴이 있으면 문자열 풀
에 String 인스턴스를 미리 만듬
이때 같은 문자열이 있으면 만들지 않음
String str4 = "hello"
는 hello 문자열 리터럴을 사용하므로 문자열 풀에서 str3과 같은 참조를 함
문자열 풀 덕분에 같은 문자를 사용하는 경우 메모리 사용도 줄이고, 성능도 최적화 가능
✅ String 클래스 대략 구조
public final class String {
//문자열 보관
private final char[] value;// 자바 9 이전
private final byte[] value;// 자바 9 이후
//여러 메서드
public String concat(String str) {...}
public int length() {...}
...
}
종류 3가지
String
: 클래스지만, 기본자료형처럼 사용하게 설정되어있음 (수정이 불가능 = 불변
)"A" + "B"
String("A") + String("B") //문자는 String 타입이다.
String("A").concat(String("B"))//문자의 더하기는 concat을 사용한다.
new String("AB") //String은 불변이다. 따라서 새로운 객체가 생성된다.
불변인 String의 내부 값은 변경할 수 없으며, 변경된 값을 기반으로 String 객체가 생성된다
String str = "A" + "B" + "C" + "D";
String str = String("A") + String("B") + String("C") + String("D");
String str = new String("AB") + String("C") + String("D");
String str = new String("ABC") + String("D");
String str = new String("ABCD");
이와 같이 많은 문자들을 더하는 경우, 3개의 String 객체가 추가로 생성된다
불변인 String 클래스의 단점 : 문자를 더하거나 변경할 때 마다 객체를 새로 생성해야함
-> CPU, 메모리 자원이 많이 사용됨
이러한 문제를 해결하기 위해서 가변 String이 나옴 -> StringBuffer, StringBuilder
StringBuffer, StringBuilder
: 클래스 사용방식으로 문자열을 다룰수 있음 (수정 가능 = 가변
)가변은 내부의 값을 바로 변경하면 되기 때문에 새로운 객체를 생성할 필요가 없다
성능과 메모리 사용면에서 불변보다 더 효율적이다
StringBuilder
는 보통 문자열을 변경하는 동안에만 사용하다가, 나중에 안전한(불변) String
으로 변환하는 것이 좋다
StringBuilder
는 주로 (반복문, 조건문, 특전 부분 변경, 대용량 문자열) 등을 다룰 때 사용함
StringBuilder sb = new StringBuilder();
sb.append("A");
sb.append("B");
sb.append("C");
System.out.println(sb); // ABC
sb.insert(3,"Java");
System.out.println(sb); // ABCJava
✅ String 최적화
ex)
String result = new StringBuilder().append(str1).append(str2).toString();
-> 이처럼 메서드가 체인으로 연결되는 것처럼 하는 기법을 메서드 체이닝
이라고 한다
-> 하나의 메서드가 호출될 때 반환되는 객체로 다시 메서드를 이어서 진행하는 기법
(1) : String.concat("문자열값")
//ex
String test = "GDJ64";
test = test.concat(" 아자아자 화이팅!"); // + 연산과 동일함
System.out.println(test); // GDJ64 아자아자 화이팅!
(2) : String.contains("문자열값") = 두개의 문자열을 합쳐주는 메소드
//ex
String test = "GDJ64";
if(test.contains("64")) { // true임
System.out.println("응 64포함됨");
}
(3) : int indexof("문자열")
//ex
String test = "GDJ64 아자아자 화이팅!";
System.out.println(test.indexOf("팅")); // 13
System.out.println(test.indexOf("아자")); // 6
System.out.println(test.indexOf("유병승")); // 해당 문자가 없을시 -1 리턴
System.out.println(test.indexOf(".",5)); // 두번째 인수 : 해당 인덱스위치부터 찾음
(4) : lastIndexof("문자열");
//ex
test = "date.test.exe";
System.out.println(test.lastIndexOf(".")); // 9
System.out.println(test.indexOf(".",test.indexOf(".")+1)); // 9
(5) : String[] split(String);
//ex
test="유병승,19,경기도시흥시,남";
String[] result = test.split(","); // 문자열을 ,로 분리해서 분리한 것들을 배열로 만듬
for(String d : result) {
System.out.print(d+" "); // 유병승 19 경기도시흥시 남
}
System.out.println();
(6) : String replace("찾을값","대체할값");
test = "나는 코딩을 정말 못해!";
String testStr = test.replace("못해", "잘해");
System.out.println(test); // 원본값 -> 나는 코딩을 정말 못해
System.out.println(testStr); // 수정값 -> 나는 코딩을 정말 잘해
(7) : String String.join("구분자",배열)
String[] testArr = {"유병승","윤지환","윤준호","윤나라","나빈"};
test = String.join("->", testArr);
System.out.println(test); // 유병승->윤지환->윤준호->윤나라->나빈
(8) : String substring(시작인덱스번호[,끝인덱스번호])
test = "수업좀 잘하세요";
testStr = test.substring(4); // 4번인덱스부터 끝까지 자름
System.out.println(testStr); // 잘하세요
testStr = test.substring(2,4); // 2번째부터 3번째까지 자름
System.out.println(testStr); // 좀
test = "test.png";
testStr = test.substring(test.indexOf(".")+1);
System.out.println(testStr); // png
testStr = test.substring(0,test.indexOf("."));
System.out.println(testStr); // test
(9) : toUppercase() / toLowerCase()
test = "AbcDefg";
testStr = test.toUpperCase(); // 영문자를 다 대문자로 바꿈
System.out.println(testStr); // ABCDEFG
testStr = test.toLowerCase(); // 영문자를 다 소문자로 바꿈
System.out.println(testStr); // abcdefg
(10) : String trim()
test = " 안녕하세요";
testStr = test.trim();
System.out.println(testStr); // 안녕하세요
(11) : valueOf()
int age = 19;
// test = (String)age; // 강제형변환으로 불가능함
test = String.valueOf(age);
System.out.println(test); // 19로 출력되지만 문자열 형태임
test=String.valueOf(180.5);
System.out.println(test); // 180.5로 출력되지만 문자열 형태임
(1) : append("문자열")
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
System.out.println(testSb); // 여러분 한시간 남았어요!
testSb.append(" 우리 힘냅시다! 보강은 어떻게 할까요?");
System.out.println(testSb); // 여러분 한시간 남았어요! 우리 힘냅시다! 보강은 어떻게 할까요?
(2) : insert(인덱스번호, 문구)
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
testSb.insert(3, "곧");
System.out.println(testSb); // 여러분곧 한시간 남았어요!
(3) : delete(시작인덱스, 끝인덱스)
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
testSb.delete(3, 5); // 3번째부터 4번째인덱스에 있는 값들 삭제
System.out.println(testSb); // 여러분한시간 남았어요!
(4) : deleteCharAt()
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
testSb.deleteCharAt(1); // 1번째 인덱스 삭제
System.out.println(testSb); // 여분 한시간 남았어요!
(5) : setCharAt(인덱스번호, "수정할문자")
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
testSb.setCharAt(1, '공'); // 1번째 인덱스 번호의 문자를 수정
System.out.println(testSb); // 여공분 한시간 남았어요!
💡 length(), substring, indexOf, replace 등 String에서 제공하는 유사한 메소드를 동일하게 제공
(6) : reverse
StringBuffer testSb = new StringBuffer();
testSb.append("여러분 한시간 남았어요!");
testSb.reverse(); // 문자열을 반전해줌
System.out.println(testSb); // !요어았남 간시한 분러여
String test0 = "java,oracle,html/css/javascript/jquery,servlet/jsp";
StringTokenizer st = new StringTokenizer(test0,",/"); // ,와 / 둘다 구분해줌
while(st.hasMoreElements()) { // 요소가 없을 때 까지 출력
System.out.println(st.nextElement());
}
while(st1.hasMoreTokens()) { // 요소가 없을 때 까지 출력
System.out.println(st1.nextToken());
}