우리가 말을 할 때, "네" 라고 간결하게 말하는 경우도 있지만 "알겠습니다" 라고 말하는 경우도 있듯이 자바에서 문자열을 사용할 수 있도록 제공해준 것이 바로 String 클래스입니다. 얼마 배우지는 않았지만 String 클래스는 아주 자주 쓰인다는 것을 일주일도 지나지 않아 알 수 있었습니다. 이러한 String을 사용할 때에 제일 처음으로 이해하고 넘어가야 하는 부분은 문자열을 생성하는 방식이 두 가지가 있다는 것입니다.
1. 문자열을 생성자의 매개변수로 만들어서 생성하기
예. String str1 = new String("안녕하세요");
2. 이미 생성되어 있던 문자열 상수를 지목하기
예. String str2 = "hello";
1번처럼 new 예약어를 사용해서 객체를 만들면, "안녕하세요"라는 문자열을 위한 메모리가 따로 할당이 되면서 객체가 새롭게 생성됩니다. 그러나 2번처럼 만들 경우에는 기존에 이미 있던 "hello"라는 문자열 상수의 메모리 주소를 가리키게 됩니다. 여기서 추가해서 str3을 똑같이 "hello"로 만들게 되면 str2와 str3은 똑같은 주소를 공유하게 되겠죠? 똑같은 문자열 상수를 적은것이니까요. 그럼 이러한 상수값을 저장하는 공간은 뭐라고 할까요? 그것은 바로 '상수 풀(constant pool)'입니다.
1. 문자열 만들기
public class Practice1 {
public static void main(String[] args) {
String str1 = new String("안녕하세요 ");
String str2 = "hello";
String str3 = str1 + str2;
String str4 = str1.concat(str2);
System.out.println(str3);
System.out.println(str4);
}
}
위처럼 str1과 str2를 각각 다른 방법으로 만들었습니다. 만드는 방법에 두 가지 다른 방법이 있는 것처럼 출력할때도 다른 방법을 사용해서 꺼내올 수 있겠습니다. 첫번째로는 단순하게 str1과 str2를 더해서 출력하는 것이고 그 다음줄에 보이시듯 String str4 = str1.concat(str2); 요렇게 출력하는 것입니다. concat이라는 함수는 문자열과 문자열을 합친 값을 리턴하는 메서드인데요, concatenate라는 단어를 짧게 쓴 것으로, 단어의 원래 뜻은 사슬같이 잇다, 라는 뜻입니다. 엑셀을 공부하신 분들이라면 이 함수가 낯이 익으실 것 같네요~ 어떻게 사용하는지는 각자의 마음이지만 이런 것이 있다 정도는 알아두는 것이 좋을 것 같습니다! 코드를 적은 방식은 다르지만 str3과 str4 안녕하세요 hello라는 같은 값이 출력되게 됩니다.
2.문자열 비교하기
String str1 = "행복함";
String str2 = "행복";
if(str1.equals(str2) == true) {
System.out.println("문자열이 일치합니다.");
}else {
System.out.println("문자열이 일치하지 않습니다.");
}
str2 = str2 + "함";
if(str1.equals(str2) == true) {
System.out.println("문자열이 일치합니다.");
}else {
System.out.println("문자열이 일치하지 않습니다.");
}
이번에는 문자열을 비교해보고 싶습니다. 프로그래밍을 함으로써 시간과 수고를 줄이는 것이 우리의 목적인데, 우리가 하나하나 맞게 적었는지 아닌지를 직접 눈이 빠져라 확인하고 있을 수는 없겠죠. 컴퓨터에게 어떻게 시키는지 알아봅시다. equals라는 함수를 써먹어보겠습니다. equal이라는 영단어는 같다는 뜻이죠. 말 그대로 문자열이 같은지, 다른지 알려주는 고마운 함수입니다. 행복함과 행복은 서로 다른 문자열입니다. equals함수가 제대로 알려주는지 테스트해봤습니다. 크게 두 부분으로 나눌 수 있겠는데요, 첫번째 시도에서는 서로 다른 문자열을 주고 일치 여부를 알려달라는 코드를 짰습니다. 역시나 문자열이 일치하지 않는다고 출력이 됐습니다. 두번째 시도에서는 "함"이란 글자를 str2에 더해줬습니다. "행복함"이 될 수 있도록 말이죠, 그랬더니 이번에는 str1과 str2가 문자열이 일치한다는 문장이 출력됐습니다.
여기서 그러면 "행복함"에서 "함"자를 제거하고( - )테스트를 돌릴 수도 있으려나? 싶은 생각이 들었다면 그 생각을 훠이훠이 날려보내야겠습니다. 예를 들어서 실제로 생각대로 코드를 작성해서 돌려보면
The operator - is undefined for the argument type(s) java.lang.String, java.lang.String
이런 문구가 뜨면서 에러가 삑 뜹니다.. 해석해보자면, 빼기 연산자는 해당 아규먼트 타입에 쓸 수 없다는 것이죠. 왜일까요? String은 자료형이 참조 자료형입니다. 즉, 위에서 "함"자를 + 를 사용해서 더했던 것은 연결 연산자를 사용한 것이죠. 우리가 습관처럼 "+"연산자를 덧붙일 때 쓰지만, 문자열에서 사용할 때는 이것이 산술연산자가 아니라 연결연산자이기 때문에 애초에 "-"는 끼어들수도 없는 것이죠!
3. 문자의 위치 탐색하기
String str1 = "가나다라마바사";
// 0123456, "가"는 0, "사"는 6
//string.IndexOf(value, startIndex);
int index = str1.indexOf('라');
int lastIndex = str1.lastIndexOf('라');
//string.lastIndexOf(value, startIndex);
//이렇게 하면 어디서부터 순서를 계산할건지 지정 가능
int lastIndex = str1.lastIndexOf('라', 7);
//startIndex의 디폴트 값은 문자열의 길이와 동일함
"가나다라마바사" 와 같은 문자열 중에 내가 원하는 특정 글자의 위치를 쉽게 알아내고 싶습니다. 이때 indexOf 함수를 쓰게 됩니다. index는 우리가 교재를 볼 때, 아 이 개념 헷갈리는데 어디에 나와있더라? 할때 책 맨 뒷쪽으로 가서 훑어보는 그 index와 동일합니다. 다만 여기서는 책의 챕터가 아니라 당신이 찾고자 하는 그 글자, 몇번째에 있어요, 하는 식으로 문자열 내의 문자의 위치를 알려주는 것이지요. str.indexOf('라')의 위치를 정수값 index로 잡고 출력해보면 3이 뜹니다. 근데 두번째로 나오는 lastIndexOf도 똑같이 3이라는 숫자가 뜹니다. 뭔가 이상합니다. last가 붙었으니 뭔지는 몰라도 다른 숫자를 뱉어줘야 하는게 인지상정 아닌지 그런 생각까지 들게 됩니다. startIndex를 넣어주면 그 차이를 확인할 수 있습니다.
구조에 대해 다시 정리를 해보겠습니다.
string.indexOf(value, fromIndex);
string.lastIndexOf(value,fromIndex);
startIndex의 디폴트 값은 문자열의 길이입니다. 만약 탐색을 시작할 위치를 지정해주지 않고 하고 싶다면 그냥 value만 넣어도 에러 없이 출력이 가능합니다.
그러면 첫번째로 indexOf에서 startIndex를 다르게 줘보겠습니다. 위에서 디폴트 값인 7이 아니라 4를 fromIndex로 지정하고 검색해보고 싶습니다. 그러면 fromIndex값을 4로 줬을 때 결과로는 -1이라는 숫자가 뜹니다. 왜일까요?
| ---------------------- | ------- |
라 -1 마
4가 가르키고 있는 문자는 '마'입니다. '라'보다 하나 뒤에 있는 숫자이지요. 그렇게 된다면 시작한 값보다 찾고자 하는 값이 뒤에 있기 때문입니다. 이런식으로, 검색을 시작하는 위치에 따라서 값이 다르게 나타납니다. 특이한 점은, 계속해서 변하는 것이 아니라, 절대적으로 fromIndex가 value의 앞에 있는지, 뒤에 있는지에 따라서 값이 달라질 뿐 상대적으로 fromIndex값을 5로 주면 -2가 나오고 2로 주면 1이 나오고 이런 것은 아니라는 점입니다.
4. 문자열의 길이 계산하기
//문자열의 길이 구하기
String str1 = "안녕하세요";
int len = str1.length();
이건 뭐 아주 간단하면서도 자주 쓰이는 함수이죠! 문자열의 길이를 쉽게 알 수 있습니다. 안녕하세요 다섯 글자의 길이를 int형으로 나타낼 수 있겠습니다.
5.문자열 부분 바꾸기
String str1= "a*b*c*d";
String repl = str1.replace("*", "-");
str1 = "5월은 가정의 달입니다.";
str1 = str1.replace(" " , "!");
셀 수 없는 공백을 지우고 싶다거나, 다르게 바꾸고 싶을 때, replace를 쓰면 되겠습니다. 예를 들어 예제처럼 각 알파벳 사이의 *를 단순한 - 로 바꾸고 싶다면 replace 함수의 첫번째 매개변수에 기존의 "*"을 적고, 바꾸고 싶은 "-"를 두번째 매개변수로 넣어주면 a*b*c*d가 a-b-c-d로 바뀌게됩니다. 마찬가지로 문장 안의 띄어쓰기도 물음표로 간단하게 바꿀 수 있겠습니다.
6. 문자열 나누기
String str1 = "1001-가나다-123-제주도";
String split[] = str1.split("-");
System.out.println(split.length);
System.out.println(Arrays.toString(split));
for(String s : split) {
System.out.println(s);
}
-로 연결된 여러 단어의 조합으로 만들어진 문자열이 있습니다. 여기서 -을 기준으로 단어를 나눠보고 싶을 때 split을 사용합니다. str1의 문자열을 나눈 후에는 split배열에 저장하도록 합니다. 그러면 총 네 개의 요소가 들어가겠죠? 당연히 length도 4가 출력됩니다. 만약 이 배열을 String형으로 보고 싶다면 Arrays.toString(split)을 해주면 됩니다. 출력값은 [1001, 가나다, 123, 제주도] 가 나옵니다. 배열 형태가 아니라 단순한 단어의 나열로 보고싶다면 향상된 포문을 사용하여 출력할수도 있겠습니다.
7. 문자열 앞 뒤 공백 삭제하기
String str1 = " hello hi bye ";
System.out.println(str1.trim());
trim은 정돈한다는 뜻을 갖고 있는데요, String클래스에서 trim은 문자열의 앞 뒤에 존재하는 공백을 지워주는 역할을 한답니다.
8. 문자열 대소문자 바꾸기
String str1 = "HELLOhi";
System.out.println(str1.toUpperCase());
System.out.println(str1.toLowerCase());
문자열이 영어 대소문자가 섞여있는경우 우리가 하나하나 고치지 않고도 컴퓨터에게 하나로 통일하라고 시킬수도 있습니다. toUpperCase의 경우에는 모두 다 대문자로 바꾸라는 것이므로 HELLOHI가 출력됩니다. 반대의 경우는 hellohi로 출력됩니다.
9. 문자열 여기서부터 저기까지 싹 다요~
String str1 = "가나다라마바사";
String str2 = str1.substring(0,3);
System.out.println("str2 :" + str2);
str2 = str1.substring(3);
System.out.println("str2 :" + str2);
문자열 내에서 우리가 원하는 범위의 값만 가져오고 싶을 때 쓸 수 있겠습니다. 만약 첫번째 경우처럼 0에서 시작한다고 지정을 하면 0번째부터 최종인덱스인 3에서 1을 뺀 값, 즉 0 1 2 의 값을 불러와 가나다를 출력합니다. 두번째 경우에는 3 숫자 하나만 줬는데요, 이런경우에는 최종인덱스를 특정해주지 않았기 때문에 컴퓨터가 알아서 3부터 문자열이 끝날때까지를 전부 다 출력하여 라마바사를 출력해줍니다.
10.문자열 내의 특정 문자 위치 파악 및 검증하기
String str1 = "가나다라마";
char c = str1.charAt(3);
System.out.println("c = " + c);
String str2 = "올 여름 무더위";
boolean a = str2.contains("무더위");
boolean b = str2.contains("겨울");
System.out.println(a);
System.out.println(b);
마지막으로 자주 쓰는 것 중 하나인 string.charAt(int index)입니다. 문자열 내의 몇번째 위치에 있는 문자값을 받고자 할 때 쓰는 것이죠. 위의 예제는 0 1 2 3, 즉 c = 라 라고 출력해줍니다. 두번째는 포함하고 있는지 아닌지만 true/false값으로 알려주는 boolean형태인데요, 특정한 문자열에, 이번 경우 같으면 "올 여름 무더위"에 "무더위"라는 단어는 있지만 "겨울"이라는 단어는 없습니다. 그러므로 boolean a는 true가 되고 boolean b는 false가 되겠죠. contain이라는 단어 자체가 뜻하는 것처럼 포함하고 있는지, 아닌지를 분명하게 보여줍니다!
'Java > 기초 Java' 카테고리의 다른 글
[기초 자바] 상속의 기초 개념(1) (0) | 2021.05.18 |
---|---|
[기초 자바] 피보나치 수열 (0) | 2021.05.13 |
[기초 자바]wrapper class (0) | 2021.05.11 |
[기초 자바] 중복되지 않는 랜덤숫자 쉽게 만들기 (1) | 2021.05.10 |
[기초 자바] 숫자 업다운해서 랜덤 숫자 맞추기 (0) | 2021.05.10 |