Part1. String 클래스
1. String클래스타입 객체생성
1) new 키워드 + 생성자호출을 통한 객체 생성
<메모리에서 일어나는 일>
일반 참조자료형 변수 객체생성과 동일하게
"new" 사용시마다 heap 영역에 문자열을 담고 있는 새로운 객체(새로운 주소값) 생성
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = new String("가나다");
String str4 = new String("가나다");
==> 상단 str1~str4는 모두 상이한 주소값을 가짐
2) 대입연산자를 통해 직접 값을 대입하여 생성: 문자열 리터럴 생성 방식
<메모리에서 일어나는 일 >
2. 대입연산자를 통해 직접 값을 넣어서 생성 :
객체 생성 이전 heap영역의 constant pool - String pool로 이동하여 같은 문자열 내용이 존재하는지 확인
==> 같은 문자열 존재시 : 신규 주소값을 만들지 않고 기존 주소값을 반환 (중복 제거)
중복에 의한메모리 낭비가 없음
==> 같은 문자열이 없을 시 : 신규 주소값 생성 및 주소값 반환
String str1 ="abc";
String str2 ="abc";
String str3 = "가나다";
String str4 = "가나다";
주소값 비교시 : str1 == str2, st3==str4
2. String클래스의 특징
1) toString, equals, hashCode메서드 오버라이딩
1] toString(): String
- 출력문에서 호출 시 String객체가 담고 있는 실제 문자열이 출력되도록 오버라이딩
2] equals(): boolean
- String객체가 담고있는 실제 문자열을 비교한 결과를 반환하도록 오버라이딩
3] hashCode(): int
- 객체의 주소값을 해싱하는 것이 아닌, 실제 문자열을 기반으로 해싱한 hashCode를 반환하도록 오버라이딩
(동일한 문자열을 기반으로 해싱하였을 경우 hashCode 결과가 같음)
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1);
=-> 참조자료형 출력시 .toString(주소값 반환메서드)이 붙어 해당 객체주소값이 출력됨
--> String형 출력시 주소값이 아닌 문자열 출력됨
(String 클래스에서 toString이 문자열을 출력하도록 오버라이딩 되어있음을 의미)
1] String클래스 equals()메서드 오버라이딩 (문자열비교)
System.out.println(str1.equals(str2)); / true
System.out.println(str1 == str2); / false, str1과 str2는 서로 다른 객체를 참조하는 주소값
2] String클래스 hashCode()메서드 오버라이딩 (문자열 같을시 같은 주소값 반환)
System.out.println(str1.hashCode()); / 서로 다른 두 객체의 hascode값(주소를 10진수로 반환)은 원래 달라야 한다!
System.out.println(str2.hashCode());
/ 그러나 출력해보면 상단 두 개의 주소값이 같음
(String클래스에서 문자열 비교하도록 오버라이딩)
3] identityHashCode : String클래스에서도 실제 주소값을 출력함
System.out.println(System.identityHashCode(str1)); // 실제주소값을 출력하면 두 값이 다름
System.out.println(System.identityHashCode(str2));
String str1 = "hello";
=> constant pool의 String pool에
바로 신규객체를 생성하는 것이 아닌, 기존 보유객체 확인 후 중복값 없을시에만 신규생성
String str2 = "hello";
System.out.println(str1);
System.out.println(str2);
System.out.println(str1.equals(str2)); // true
System.out.println(str1.hashCode()); // 99162322
System.out.println(str2.hashCode()); //99162322
System.out.println(System.identityHashCode(str1)); //1829164700
System.out.println(System.identityHashCode(str2)); //1829164700
System.out.println(str1 == str2); // true
2) String 클래스는 불변(immutable)객체
: String클래스 객체가 변수에 할당되면 참조를 업데이트하거나 내부 상태를 어떤 방법으로도 변경할 수 없음
변수에 새로운 값을 대입하면, 참조를 업데이트하는 것이 아니라
새로 생성한 객체(또는 기존 String pool에 존재하는 객체)의 주소값을 새로 대입하는 개념
(변수와 연결이 끊긴 기존 객체는 GC가 치워줌)
String str = "hello";
System.out.println(System.identityHashCode(str)); // 1829164700
==> string pool 내에 문자열 "hello"가 가지고 있는 주소값 반환
str = "Goodbye";
==> *String은 불변클래스이므로, 기존 객체에 새로운 값 저장이 불가함
==> 새로운 값을 대입했을 경우,
우선적으로 heap 영역 Constant Pool에서 Goodbye 문자열 검색 후
존재할 경우 해당 주소를 str에 대입,
존재하지 않을 경우 새로운 객체를 생성하여 신규 주소값을 str에 대입
변수와 연결이 끊긴 객체 "hello"는 gc가 치워줌
System.out.println(System.identityHashCode(str)); // 2018699554
// str 에 "Goodbye"대입시
3. StringBuffer / StringBuilder
- String클래스의 특징, "불변성"으로 인한 문자열 조작시의 메모리 낭비 해결법
String형 변수는 조작(수정, 추가, 삭제)시마다 새로운 공간을 할당 --> 메모리 낭비 발생!
이를 막기 위해 임시공간(buffer)을 준비 ,
임시공간에 문자열을 담아두었다가 한번에 처리하는 StringBuffer, StringBuilder 클래스가 있음
(동시제어기능 유무에 따라 나뉨)
1) StringBuffer
동시제어 기능 있음
* Thread-safe란: 멀티스레드프로그래밍에서 어떤 변수에 동시 접근시 안전변경을 보장
- append: 기존 문자열에 문자열을 이어붙이는 메서드
StringBuffer sb = new StringBuffer();
sb.append( 추가할 문자열 );
StringBuffer sb = new StringBuffer();
sb.append("hello");
System.out.println(sb.hashCode()); // 1829164700
System.out.println("hello".hashCode()); // 99162322
sb.append("World!");
System.out.println(sb.hashCode()); // 1829164700
System.out.println("helloWorld!".hashCode());// -933562815
System.out.println(sb); // helloWorld!
- insert메서드
StringBuffer sb = new StringBuffer();
sb.insert(추가를 시작할 index, 추가할 문자열 );
StringBuffer sb = new StringBuffer();
sb.append("this is Friday.");
sb.insert(8, "happy happy ");
System.out.println(sb); // this is happy happy Friday.
- subString메서드
StringBuffer sb = new StringBuffer();
sb.insert(삭제를 시작할 index, 끝 index );
StringBuffer sb = new StringBuffer();
sb.append("Time to go Home");
System.out.println(sb.substring(0, 4)); // to go home
2) StringBuilder
StringBuffer와 동일기능
동시제어(Thread Safe)기능이 없는 클래스
간단 프로그램, 동시제어를 다른프로그램이 제공하는 경우 사용
4. 기타 String클래스 메서드
1. 문자열.charAt(int index) : char
char ch = str1.charAt(4);
System.out.println(ch);
2. 문자열.concat(String str) : String
기존 문자열에 전달받은 또 다른 문자열을 하나로 합쳐서 반환
문자열 + 전달받은 문자열
String str2 = str1.concat("!!!");
System.out.println("str2 : "+str2);
3. 문자열.length() : int
문자열의 길이 반환
System.out.println("str1의 길이: "+ str1.length());
4-1 문자열.substring(int beginIndext) : String
문자열의 beginIndex의 위치에서 문자열 끝까지의 문자열을 추출하여 리턴
4-2 문자열.substring(int beginIndext, endIndex) : String
문자열의 beginIndex의 위치에서 endIndex-1 까지의 문자열을 추출하여 리턴
System.out.println(str1.substring(6));
System.out.println(str1.substring(0, 6));
5. 문자열.replace(char old, char new) :String
문자열에서 old문자를 new문자로 변환한 문자열을 리턴
String str3 = str1.replace('l', 'x');
==> str1은 불변자료형이므로 내용이 바뀌는게 아니라 바뀐 값을 리턴 => 새로운 변수에 담아주기
System.out.println(str3);
6. 문자열.trim() :String
--> 문자열의 맨 앞과 맨뒤의 공백을 제거한 문자열을 리턴
String str4 = " 집 에 갈 래 ";
System.out.println(str4.trim());
7. toUpperCase() ==> 모든 문자열 대문자로
toLowerCase() -> 모든 문자열 소문자로
System.out.println(str1.toUpperCase());
System.out.println(str1.toLowerCase());
8. 문자열.toCharArray() :char[]
문자열의 각 문자들을 char[]형 배열에 옮겨담은 후 해당배열 리턴
char[] chArr = str1.toCharArray();
5. String Tokenizer : 문자열 분리하기
1) 구분자를 제시하여 해당 문자열을 분리하는 방법 (배열)
2) 분리된 각각의 문자열을 토큰으로 취급하는 방법 (토큰)
1) split
문자열.split(String구분자) : String[ ] ==> String형 배열을 반환한다 (인덱스에 각 값을 담아서 반환)
String[] arr = str.split(",");
1] 일반 for문을 이용한 배열내용(인덱스)출력
for( int i =0; i < arr.length ; i++) {
System.out.println(arr[i]);
}
2] 향상된 for문을 이용한 배열내용 출력
for(String s: arr) {
System.out.println(s);
}
2) String Tokenizer이용
1. 객체 생성
StringTokenizer stn = new StringTokenizer(문자열, 구분자)
2. java.util.tokenizer 클래스 임포트
[1] 생성자
public StringTokenizer(String str); | 전달된 매개변수 str을 default delim으로 문자열 분리 ( \t,\n,\r) |
public StringTokenizer(String str,String delim); | delim(두 번째 매개변수)로 문자열을 분리 |
public StringTokenizer(String str,String delim,boolean returnDelims); | str을 delim을 기준으로 분리시 token에 delim 포함여부 (true -> 포함, false->불포함) |
[2] 주요메소드
countToken : int | 토큰의 개수 리턴 |
nextToken() : String nextToken (String delim) nextElement(): Object |
다음 토큰 리턴, 리턴후 해당 토큰은 삭제됨 (탐색후 소비됨) |
hasMoreToken() : boolean hasMoreElement() : boolean |
리턴할 다음토큰이 있는지 여부 확인 (t/f) |
StringTokenizer stn = new StringTokenizer(new String("오늘은 즐거운 기차여행 가는 날")," ");
System.out.println("분리된 문자열 갯수: "+stn.countTokens());
// ==> .countTokens() 구분자로 분리된 문자열이 몇개인지 반환해주는 메서드
for (int i=0; i <stn.countTokens(); i++) {
System.out.println(stn.nextToken());
}
StringTokenizer stn2 = new StringTokenizer(new String("오늘은 즐거운 기차여행 가는 날")," ");
System.out.println("분리된 문자열 갯수: "+stn2.countTokens());
while (stn2.hasMoreTokens()) {
System.out.println(stn2.nextToken());
분리된 문자열 갯수: 5
오늘은
즐거운
기차여행
가는
날
3) StringTokenizer와 Spilt의 차이
- StringTokenizer는 문자 또는 문자열로 문자열을 구분한다면, split는 정규표현식으로 구분합니다.
StringTokenizer는 빈 문자열을 토큰으로 인식하지 않지만 split는 빈 문자열을 토큰으로 인식하는 차이가 있습니다.
StringTokenizer는 결과값이 문자열이라면 split는 결과 값이 문자열 배열입니다.
따라서 StringTokenizer를 이용할 경우 전체 토큰을 보고싶다면 반복문을 이용해 하나하나 뽑을 수 밖에 없습니다.
Part2
1. Wrapper클래스란?
- 기본자료형을 객체(참조자료형)로 포장해주는 클래스
* * boolean, char, byte, short, int, long, float, double <--->
* Boolean, Character, Byte, Short, Integer(중요), Long, Float, Double
기본자료형을 객체로 취급해야 하는 경우(Wrapper클래스가 필요한 때):
메소드의 매개변수로 기본자료형이 아닌 객체타입이 들어가야할 떄 *
다형성을 적용시키고 싶을 떄
int num1 = 10;
int num2 = 15;
* num1과 num2동등비교
System.out.println(num1== num2); : 기본형 연산시 주소값이 하닌 실제 저장값 비교, 결과:false
System.out.println(num1.equals( num2) ); : 오류! equals는 Object클래스 메서드 (주소값을 비교하는메서드)
Object는 모든클래스의 최고조상, Object메소드는 참조자료형 어디서든 쓸수있다
그러나 기본자료형은 객체가 아니므로 Object메소드를 상속받지 못함
==? 기본자료형의 주소값을 비교하고 싶을때==> 객체화가필요할 떄
// Integer i1 = new Integer(num1); 이렇게 쓰지 않고
Integer i1 = num1;
Integer i2 = num2;
System.out.println(i1.equals(i2));
<기타>
1. 연산자 우선순위 복습
String a = "a";
String b = "a";
System.out.println("결과 : "+ a==b); // 결과 : false !
/ 연산자 우선순위에 의해서 ("결과: "+a ) 가 먼저 수행됨
System.out.println("결과 : "+ (a==b)); // 결과 : true
thread란?
thread safe, 동기화란?
향상된 for문
향상된 for문:
초기, 조건, 증감식 없음
배열처럼 여러 요소, 인덱스로 이루어진 집합의 모든 요소에 대해
특정 작업을 반복하기 위해 사용 (ArrayList요소, 배열 인덱스 출력 등)
단순출력만 가능하며 배열의 값 수정불가
[표현법]
for (배열a의 각 인덱스를 받아줄 변수:순차적으로 접근할 배열a) {
}
* 일반 for문과 비교
String[] sArr = {"오늘은 토요일"};
for( int i=0; i <sArr.length; i++) {
System.out.println(sArr[i]);
}
초기식, 조건식(배열의 길이), 증감식
그리고 인덱스에 지역변수 대입까지
번거롭다!
String[] sArr = {"오늘은 토요일"};
for( String str : sArr ) {
System.out.println(str);
}
배열명만 가지고
배열을 받아줄 변수 지정 후 출력가능
String클래스의 경우 변수명으로 바로 출력가능 (toString오버라이딩)
'코딩공부일지 > 수업 review' 카테고리의 다른 글
컬렉션 개념, ArrayList (0) | 2022.09.22 |
---|---|
자바: abstract & interface & 예외 (0) | 2022.09.21 |
자바: 다형성 (0) | 2022.09.20 |
자바 - 상속 & 오버라이딩 (0) | 2022.09.20 |
자바 - 객체지향프로그래밍2( 오버로딩, 객체배열) (0) | 2022.09.14 |