문자열 리터럴은 String 객체로 자동 생성되지만
String 클래스를 이용하면, 다양한 생성자로 직접 String 객체를 생성할 수 있다.
char[] 와 메서드(기능)를 결합한 것
문자열을 많이 사용하기 때문에 특별하게 만들어진 클래스
name = name + firstName;
String name = "choi"; 와 String firstName = "wb"; 가 있을 경우,
기존의 name 은 firstName과 합쳐져서 새로운 name이 된다. (기존의 name을 대체하게 됨)
String은 읽기만 가능. 수정은 불가능
String str = "Java";
str = str + "Good";
System.out.println(str); // JavaGood
String a = "가";
String b = "나";
a = a + b; // a = "가나"
'+ 연산자'를 이용해서 문자열을 더할 경우,
매 연산마다 새로운 문자열을 가진 Stirng 인스턴스가 생성되어, 메모리 공간을 차지하게 된다
추가만 됐을 뿐, 기존의 문자열에는 수정이 이뤄지지 않음
StringBuffer 인스턴스에 저장된 문자열을 변경하므로,
하나의 인스턴스만으로도 문자열을 다룰 수 있게 된다.
참고: StringBuffer 클래스
참고: string, stringbuffer, stringbuilder
char charAt(int index)
해당 문자열의 특정 인덱스에 해당하는 문자를 반환함.
int compareTo(String str)
해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교함.
int compareToIgnoreCase(String str)
해당 문자열을 인수로 전달된 문자열과 대소문자를 구분하지 않고 사전 편찬 순으로 비교함.
String concat(String str)
해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환함.
int indexOf(int ch)
, int indexOf(String str)
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환함.
int indexOf(int ch, int fromIndex)
, int indexOf(String str, int fromIndex)
해당 문자열에서 특정 문자나 문자열이 전달된 인덱스 이후에 처음으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch)
해당 문자열에서 특정 문자가 마지막으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch, int fromIndex)
해당 문자열에서 특정 문자가 전달된 인덱스 이후에 마지막으로 등장하는 위치의 인덱스를 반환함.
String[] split(String regex)
해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
String substring(int beginIndex)
해당 문자열의 전달된 인덱스부터 끝까지를 새로운 문자열로 반환함.
String substring(int begin, int end)
해당 문자열의 전달된 시작 인덱스부터 마지막 인덱스까지를 새로운 문자열로 반환함.
단, 마지막 end는 포함 X
String toLowerCase()
해당 문자열의 모든 문자를 소문자로 변환함.
String toUpperCase()
해당 문자열의 모든 문자를 대문자로 변환함.
String trim()
해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거함.
length()
해당 문자열의 길이를 반환함.
isEmpty()
해당 문자열의 길이가 0이면 true를 반환하고, 아니면 false를 반환함.
char[] toCharArray()
문자열을 문자배열(char[])로 변환해서 반환함.
repeat()
String 문자열을 파라미터의 주어진 횟수만큼 반복
join()
Java 8에서 추가된 메소드
문자열을 결합하기 위한 메서드 (split 메서드의 반대라고 생각하면 됨)
class Ex {
public static void main(String args[]) {
String str3 = new String("example");
String str4 = new String("example");
}
}
class Ex {
public static void main(String args[]) {
String str1 = "apple";
String str2 = "apple";
}
}
string constant pool 영역에 존재
→ 같은 메모리 주소를 갖는다.
문자열 리터럴이 같은 내용이라면, 한 번만 저장된다.
리터럴 방식의 장점?
String 의 특성상 리터럴 방식이 메모리 절약 차원에서 유리하다.('new'로 선언했을 때와는 달리) String 이 리터럴 방식으로 선언되었을 때는
변수마다각자 다른 개별 공간이 아닌, '스트링 상수 풀 String constant pool'이라는 공동 공간에 문자열이 저장된다..
(공동 공간에 저장된다면, 메모리 주소 또한 같은 메모리 주소를 갖는다는 것)
String[] name = new String[3];
name[0] = new String("Kim");
name[1] = new String("Park");
name[2] = new String("Yi");
// new 연산자 없이도 생성은 가능하나, 위의 방식이 정석적인 방법
String[] name = new String[3];
name[0] = "Kim";
name[1] = "Park";
name[2] = "Yi";
String[] name = new String[] {"Kim", "Park", "Yi"}
String[] name = {"Kim", "Park", "Yi"}
byte[] 배열
// 배열 전체를 String 객체로 생성
String str = new String(byte[] bytes);
// 지정한 문자셋으로 디코딩
String str = new (byte[] bytes, String charsetName);
// 배열의 offset 인덱스 위치부터 length만큼 String 객체로 생성
String str = new (byte[] bytes, int offset, int length);
// 지정한 문자셋으로 디코딩
String str = new (byte[] bytes, int offset, int length, String charsetName);
byte[] → 문자열 변환
public class ByteToStringExample {
public static void main(String[] args) {
byte[] bytes = {72, 101, 108, 108, 111, 32, 74, 97, 118, 97}
String str1 = new String(bytes);
System.out.println(str1);
String str2 = new String(bytes, 6, 4); // 6 은 74 인덱스의 위치, 4 는 4개 를 뜻함
System.out.println(str2);
}
}
/* 실행 결과
Hello Java
Java */
public class StringGetBytesExamplet {
public static void main(String[] args) {
String str = "안녕하세요";
// 기본 문자셋으로 인코딩 & 디코딩
byte[] bytesl = str.getBytes();
System.out.println("bytes1.length: " + bytes1.length
String str1 = new String(bytes1);
System.out.println("bytes1->String: " + str1);
try {
// EUC-KR 을 이용해서, 인코딩 & 디코딩
byte[] bytes2 = str.getBytes("EUC-KR");
System.out.println("bytes2.length: " + bytes2.length);
String str2 = new String(bytes2, "EUC-KR");
System.out.println("bytes2->string: " + str2);
// UTF-8 을 이용해서, 인코딩 & 디코딩
byte[] bytes3 = str.getBytes("UTF-8");
System.out.println("bytes3. length: " + bytes3.length);
String str3 = new String(bytes3, "UTF-8");
System.out.println("bytes3->string: " + str3);
} catch (Unsupport tedEncodingException e) {
e.printstackTrace();
}
}
}
/* 실행결과
bytes.length: 10
bytes1->String: 안녕하세요
gC토프")i0xebnt.iosicue I bytes2.length: 10
:(nofisso/)n| bytes2->string: 안녕하세요
bytes3.length: 15
bytes3->String: 안녕하세요 */
문법
String str = "ABCDE";
char ch = str.charAt(3); // D가 ch에 저장됨
방법 1 : String타입의 참조변수 뒤에 붙여서 사용
String str = new String();
char c = ' '; // char타입의 변수 c를 선언
str = "안녕하세요"; // String타입의 참조변수 str에 "안녕하세요"라는 문자열을 저장
c = str.charAt(0); // 변수 c에 str.charAt(0)의 값을 저장 → 'str이 가리키고 있는 문자열에서 0번째에 있는 문자를 char타입으로 변환한다.'
System.out.println(c);
/* 출력 결과
안 */
방법 2 : Scanner에서 next() 또는 nextLine() 뒤에 붙여서 사용
Scanner sc = new Scanner(System.in);
char c1 = ' ';
char c2 = ' ';
// String타입의 참조변수 뒤에 붙이지 않고, 입력받는 곳에 바로 붙여도 동일하게 사용 가능 → char타입의 변수 c1과 c2에 바로 저장
c1 = sc.next().charAt(0);
c2 = sc.nextLine().charAt(3);
System.out.println(c1);
System.out.println(c2);
sc.close();
매개값으로 주어진 인덱스의 문자를 리턴
(인덱스 : 0 ~ 문자열 길이-1)
String으로 저장된 문자열 中 한 글자만 선택해서 char타입으로 변환
→ charAt() 은 String타입을 char타입으로 변환할 때 사용!
참고: ==, equals() - 2. equals()
public class StringIndexOfExample {
public static void main(String[] args) {
String subject = "자바 프로그래밍";
int location = subject.indexOf("프로그래밍"); // subject 참조변수에서 "프로그래밍" 문자열이 시작되는 인덱스를 리턴
System.out.println(location); // 리턴값을 출력
// "자바" 문자열을 포함하고 있지 않는 경우가 아니라면 (즉, "자바" 를 포함하고 있다면)
if (subject.indexOf("자바") != -1) { // 주어진 문자열이 포함되어 있지 않으면, -1 을 리턴하기 때문에 이런 식으로 표현했음
System.out.println("자바와 관련된 책이다.");
} else {
System.out.println("자바와 관련없는 책이다.");
}
}
}
/* 출력 결과
3
자바와 관련된 책이다. */
매개값으로 주어진 문자열이 시작되는 인덱스를 리턴
만약, 주어진 문자열이 포함되어 있지 않으면, -1 을 리턴
참고: 배열, ArrayList - ArrayList - (5) 값 검색
예시 : 일반 문자열
public class StringReplaceExample {
public static void main(String[] args) {
String oldstr = "자바는 객체 지향 언어입니다. 자바는 풍부한 API를 지원합니다.";
String newstr = oldstr.replace("자바", "JAVA");
System.out.println(oldstr);
System. out.println(newstr);
}
}
/* 실행 결과
자바는 객체 지향 언어입니다. 자바는 풍부한 API를 지원합니다.
JAVA는 객체 지향 언어입니다. JAVA는 풍부한 API를 지원합니다.
*/
예시 2 : 특수문자
public static void main(String[] args) {
String old = "abh.cd";
String.newchar = old.replaceAll(".", "z"); // 특수문자 . 이 z로 변환됨
System.out.print(newchar);
}
/* 출력 결과
abhzcd */
replace(바꾸고 싶은 문자, 바꿀 문자)
특수문자로 치환이 가능
예시 1 : 특수문자
public static void main(String[] args) {
String old = "abz.cd";
String.newchar = old.replaceAll(".", "z"); // 모든 문자열이 z로 변환됨
System.out.print(newchar);
}
/* 출력 결과
zzzzz */
예시 2 : 숫자
public static void main(String[] args) {
String old = "05784362변환";
String.newchar = old.replaceAll("[0-9]", "숫자");
System.out.print(newchar);
}
/* 출력 결과
숫자숫자숫자숫자숫자숫자숫자숫자변환 */
replaceAll(바꾸고 싶은 문자, 바꿀 문자)
특수문자로 치환이 어렵다.
public static void main(String[] args) {
String old = "abcad";
String.newchar = old.replaceFirst("a", "z");
System.out.print(newchar);
}
/* 출력 결과
zbcad */
// 예시 1
String original = "Java Programming"; // 원래의 original 변수에서 "Java Programming" 문자열이 변경된 것은 아님!
String lowerCase = original.toLowerCase(); // lowerCase 변수는 새로 생성된 "java programming" 문자열얼 참조
String upperCase = original.toUpperCase(); // upperCase 변수는 새로 생성된 "JAVA PRIGRAMMING" 문자열얼 참조
toLowerCase() : 모든 문자열을 소문자로 변환
toUpperCase() : 모든 문자열을 대문자로 변환
영어로 된 문자열을 대소문자와 관계없이 비교할 때 주로 사용
public class StringToLowerUpperCaseExample {
public static void main(String[] args) {
String str1 "Java Programming";
String str2 = "JAVA Programming";
System.out.println(str1.equals(str2);
String lowerStr1 = str1.toLowerCase();
String lowerStr2 = str2.toLowerCase();
System.out.println(lowerStr1.equals(lowerStr2));
// equalsIgnoreCase() 메소드를 사용하면, toLowerCase() & toUpperCase()로 대소문자 맞추고나서 equals()를 이용해야하는 번거로움 없어짐
System.out.println(str1.equalsIgnoreCase(str2));
}
}
/* 출력 결과
false
true
true */
equalsIgnoreCase() : 대소문자 구분 X
equals() : 대소문자 구분 O
public class StringTrimExample {
public static void main(String[] args) {
String tel1 = " 02";
String tel2 = "123 ";
String tel3 = " 1234 ";
String tel = tel1.trim() + tel2.trim() + tel3. trim();
System.out.println(tel);
}
}
/* 실행 결과
021231234 */
참고: Enum 클래스 (enumeration type, 열거체) - (2) valueOf() 메소드
String str = "Apple,Amazone,Google,Microsoft";
String[] list = str.split(",");
/* 실행 결과
[Apple, Amazon, Google, Microsoft]
*/
String str = "Apple Amazon Google Microsoft";
String[] list = str.split(" ");
/* 실행 결과
[Apple, Amazon, Google, Microsoft]
*/
String animals = "dog, cat";
String[] arr = animals.split(",");
String arr = String.join("-", arr);
System.out.println(str);
/* 출력 결과
dog-cat
*/
public class Main {
public static void main(String[] args) {
// 실험 1
String str1 = "hello world";
String str2 = str1.substring(5);
System.out.println(str1); // 실행 결과 : hello world
System.out.println(str2); // 실행 결과 : world
// 실험 2 : String 클래스의 문제점 1
// 겉으로 보이는 모습
String str3 = str1 + str2; // "hello world" + " world"
System.out.println(str3); // 실행 결과 : hello world world
// 실제 모습
String str4 = new StringBuffer().append(str1).append(str2).toString();
System.out.println(str4); // 실행 결과 : hello world world
// 실험 3 : String 클래스의 문제점 2
String str5="";
for (int i = 0; i < 10; i++) {
str5 = str5 + "*";
}
System.out.println(str5); // 실행 결과 : **********
// 실험 4 : 해결법
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append("*");
}
String str6 = sb.toString();
System.out.println(str6);
}
}
실험 2
실험 3
실험 4
참고: String 클래스
참고: [자바 프로그래밍 기초] 4. charAt()에 대해서 알아보자.
참고: 자바 특정 문자 & 특수 문자 제거/치환하기 (replace, replaceAll, replaceFirst)함수 사용
참고: 완벽정리! 자바 string 문자열을 배열로 분리하기