본문 바로가기

코딩/JAVA 공부

[JAVA] 자바의 정석 _ Object, String, StringBuffer, StringBuilder, Math 클래스 / 오토박싱, 언박싱

 * Object 클래스

- 모든 클래스의 최고 조상. 오직 11개의 메서드만 가지고 있음.

Object 클래스의 메서드  
protected Object clone() 객체 자신의 복사본 반환 / 오버라이딩 후 public으로 변경해줘여함.
public boolean equals(Object obj) 객체 자신과 객체 obj가 같은 객체인지 알려줌. (같으면 true)
protected void finalize() 생성자와 반대 / 오버라이딩 후 public으로 변경해줘여함.
객체가 소멸될 때 가비지 컬렉터에 의해 자동적 호출.
public Class getClass() 객체 자신의 클래스 정보를 담고 있는 Class인스턴스 반환
public int hashCode() 객체 자신의 해시코드 반환
public String toString() 객체 자신의 정보를 문자열로 반환
public void notify() 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다.
public void notifyAll() 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨운다
public void wait()
public void wait(long timeout)
public void wait(long timeout, int nanos)
다른 쓰레드가 notify()나 notifyAll()을 호출할 때 까지 현재 쓰레드를 무한히 또는 지정된 시간 동안 기다리게한다.

 

 * boolean equals(Object obj)

객체의 주소를 비교해 같으면 true, 다르면 false 반환.

주소 말고 값을 비교하고 싶으면 오버라이딩 해야함.

근데, equals 메서드에 매개변수는 Object형 이므로, 매개변수 형변환이 필요!!

class Value{
    int value;
    
    Value(int value){
    	this.value = value;
    }
    // Object의 equals메서드 오버라이딩.
    public boolean equals(Object obj){
    	// 참조변수의 형변환 전에는 반드시 instanceof로 확인해야함.
        if(!(obj instanceof Value)) return false;
    	Value v = (Value)obj; // obj를 Value로 형변환
        return this.value==v.value;

 

 * hashCode()

- 객체의 해시 코드(hash code)를 반환하는 메서드. 객체의 주소를 int로 변환해서 반환.

네이티브 메서드 : OS의 메서드. 내용은 이미 OS에 작성돼있음.

public class Object{
    ....
    public native int hashCode(); // 네이티브메서드로 내용을 볼 순 없음.
    }

- equals()를 오버라이딩 하면, hashCode()도 오버라이딩 해야함.

equals()의 결과가 true인 두 객체의 해시 코드는 같아야 하기 때문!!!

 

 * toString()

- 객체를 문자열로 변환하기 위한 메서드

public String toString(){
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

보통 오버라이딩 해서 사용

class Card{
    String kind;
    int number;
    
    Card(){
    	this("SPACE", 1);
    }
    
    Card(String kind, int number){
    	this.kind = kind;
        this.number = number;
    }
    
    public boolean equals(Object obj){ // equals 오버라이딩
    	if(!(obj instanceof Card))
        	return false;
            
        Card c = (Card)obj;
        return this.kind.equals(c.kind) && this.number == c.number;
    }
    // equals 오버라이딩 하면 hash도 오버라이딩 해야함.
    public int hashCode(){
    	return Objects.hash(kind, number); // Objects 클래스는 객체와 관련된 메서드 제공하는 유틸 클래스
                                           // hash는 가변인자임.
    
    public String toString(){ // toString 오버라이딩
    	return "kind: " +kind+ ", number: " +number;
    }
} //class end

 

 * String 클래스

- 문자열을 다루기 위한 클래스, 데이터 char[] + 메서드(문자열 관련) 로 이뤄짐.

- 내용을 변경할 수 없는 불변(immutable) 클래스 : 덧셈 연사자(+)를 이용한 문자열 결합은 성능이 떨어짐.

문자열의 결합, 변경이 많은 경우 StringBuffer 클래스 사용.

 

문자열의 비교

- String str = "abc" ;vs String str = new String("abc"); 비교

객체 생성이 달라진다.

String str1 = "abc";
String str2 = "abc";
String str3 = "abc";
String str4 = "abc";

위 그림처럼 되는 이유!

문자열 리터럴(상수)은 프로그램 실행 시 자동으로 constant pool에 생성, 저장된다.

따로 저장하고 있다가 여러 참조 변수가 공유할 수 있도록 공유.

--> 이런 이유 때문에 String class로 문자열 내용 변경 불가!

 * == 와 equals 비교

- == 은 두 객체의 주소를 비교함

equals는 객체 안의 내용을 비교함. 따라서 문자열의 내용 비교할 땐 equals를 사용해야 한다.

(String 클래스는 자체적으로 equals를 오버라이딩 해둔 상태여서 주소 비교 x)

 

* String 클래스의 생성자와 메서드

String(char[] value) char 배열을 String형으로 변경
String(StringBuffer buf) StringBuffer인스턴스가 갖고있는 문자열과 같은 String 인스턴스 생성
char charAt(int index) 문자열에서 인덱싱한 부분 char 반환
int compareTo(String str) str과 사전 순서로 비교, 같으면0, 작으면 -1, 크면 +1 반환.
앞에서부터 비교함. (정렬시 사용)
String concat(String str) str을 뒤에 덧붙임
boolean contains(CharSequence s) s가 포함되었는지 검사. 있으면 true 반환
boolean endsWith(String suffix) suffix로 끝나는지 검사
boolean startWith(String prefix) prefix로 시작하는지 검사
boolean equals(Object obj) obj와 문자열 비교. obj가 String이 아니거나, 문자열이 다르면 false 반환
boolean equalsIgnoreCase(String str) str과 문자열 대소문자 구분 없이 비교.
int indexOf(char ch) ch가 문자열에 존재하는지 확인하고 위치 반환, 없으면 -1 반환
int indexOf(char ch, int pos) ch가 문자열에 존재하는지 pos부터 확인.
int indexOf(String str) 주어진 문자열이 존재하는지 확인,  시작지점 알려줌
int lastIndexOf(char ch) ch가 문자열에 존재하는지 뒤에서부터 찾아 위치 반환.
int lastIndexOf(String str) 오버로딩!
int length() 문자열 길이 반환
String[] split(String regex) 문자열을 지정된 분리자(regex)로 나누어 문자 배열에 담아 반환.
String[] split(String regex, int limit) split 으로 나눠지는 배열 개수 지정
String substring(int begin)
String substring(int begin, int end)
begin 부터 end 범위에 포함된 문자열 얻는다. end가 없으면 제일 끝까지
String toLowerCase() 모든 문자열을 소문자로 변환해 반환
String toUpperCase() 모든 문자열을 대분자로 변환해 반환
String trim() 문자열 왼쪽 끝, 오른쪽 끝에 있는 공백 없앤 결과 반환
static String valueOf(기본형) 지정된 값을 문자열로 변환해 반환,
참조변수의 경우 toString()을 호출한 결과를 반환.
String join(String p, String[] arr) 여러 문자열 사이에 구분자 p를 넣어서 결합

 * 문자열과 기본형 간의 변환

- 숫자를 문자열로 바꾸는 방법 : 숫자 + 빈 문자열 , valudOf

int i = 100;
String str1 = i+"";
----------------------
String str2 = String.valueOf(i);

- 문자열을 숫자로 바꾸는 방법

int i = Integer.parseInt("100");
int i2 = Integer.valueOf("100");
Integer i2 = Integer.valueOf("100");

 

 * StringBuffer 클래스

- String처럼 문자형 배열(char [])을 내부적으로 가지고 있다.

- 내용 변경 가능!

StringBuffer sb = new StringBuffer("abc");
// "abc"
sb.append("123");
//"abc123"

- 배열은 길이 변경 불가, 공간이 부족하면 새로운 배열 생성해야,,

  StringBuffer는 저장할 문자열 길이를 고려해서 적절한 크기로 생성해야 함.

public StringBuffer(int length){
    value = new char[length];
    shared = false;
}
public StringBuffer(){
    this(16);
}

public StringBuffer(String str){
    this(str.length() + 16);
    append(str);
}

- append()는 지정된 내용을 StringBuffer에 추가 후, StringBuffer의 참조를 반환. 즉 새로운 객체를 반환하는 게 아님.

- StringBuffer는 equals()가 오버라이딩 되어있지 않다! (주소 비교) --> String으로 변환 후 equals()로 비교.

 

 * StringBuffer의 생성자와 메서드

StringBuffer() 16문자를 담을 수 있는 인스턴스 생성
StringBuffer(int length) length길이의 인스턴스 생성
StringBuffer(String str) str을 갖는 인스턴스 생성
StringBuffer append(매개변수) 매개변수로 입력된 값을 문자열로 변환해 문자열 뒤에 덧붙임.
int length() StringBuffer 인스턴스에 저장된 문자열의 길이 반환
int capacity() StrinfBuffer인스턴스의 버퍼 크기(char[] 크기)를 알려줌
char charAt(int index) index 위치에 있는 문자 반환
StringBuffer delet(int start, int end) start 부터 end사이에 있는 문자 제거 (끝 위치 제외)
StringBuffer deleteCharAt(int index) index 위치 문자 제거
StringBuffer insert(int pos, 매개변수) 매개변수를 문자열로 변환해 pos에 추가
StringBuffer replace(int start, int end, String str) start 부터 end 사이에 있는 문자를 str로 바꿈 (끝 위치 제외)
StringBuffer reverse() 문자열의 순서를 거꾸로 나열
void setCharAt(int index, char ch) index위치의 문자를 ch로 바꿈
void setLength(int newLength) 지정된 길이로 문자열의 길이 변경. 빈공간은 널문자 '\u0000'로 채운다.
String toString() String으로 변환
String substring(int start)
String substring(int start, int end)
start 부터 end까지 String으로 뽑아서 반환

 

 * StringBuilder 클래스

- StringBuffer와 거의 비슷. 차이점은 StringBuilder는 동기화 되어있다. 멀티 쓰레드에 안전!

 - 싱글 쓰레드: 한 번에 1개 작업, 동기화 필요 X

 - 멀티 쓰레드: 한번에 n개 작업

 - 동기화: 멀티 쓰레드에서 작업 간에 데이터 보호.

 

 * Math 클래스

- 수학 관련 static메서드의 집합.

static double abs(double a) 절대값 반환
static double ceil(double a) 주어진 값을 올림하여 반환
static double floor(double a) 주어진 값을 버림하여 반환
static double max(double a, double, b) a,b 중 큰 값 반환
static double min(double a, double b) a,b 중 작은 값 반환
static double random() 0.0~ 1.0 범위의 임의의 double값 반환
static double rint(double a) a와 가장 가까운 정수값을 double형으로 반환,
정 가운데는 짝수를 반환 (sum의 오차를 줄여줌)
static long round(double a) 소수점 첫째자리에서 반올림한 정수값 반환

 

 * wrapper 클래스

- 기본형 값을 감싸는 클래스/ 8개의 기본형을 객체로 다뤄야 할 때 사용하는 클래스.

public final class Integer extends Number implements Comparable{
    private int value;
    ....
}
기본형 wrapper 클래스 생성자 활용 예시
boolean Boolean Boolean(boolean value)
Boolean(String s)
Boolean b = new Boolean(true);
char Character Character (char value) Character c = new Character('a');
byte Byte Byte(byte value) Btye b = new Byte(10);
short Short Short(short value) Short s = new Short(10);
int Integer Integer(int value) Integer i = new Integer(100);
long Long Long(long value) Long l = new Long(100);
float Float Float(float value) Float f = new Float(1.0f);
double Double Double(double value) Double d = new Double(1.0);

 

 * 오토박싱, 언박싱

기본형과 참조형(wrapper 클래스) 사이에 변환을 자동을 해줌.

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(100));
list.add(100); // 오토 박싱으로 자동 객체 생성

Integer i = list.het(0);
int i = list.get(0).intValue();
int i = list.get(0) // 오토 언박싱으로인해 intValue() 안해도 괜찮음.

list에 객체만 저장 가능한데, 오토박싱으로 인해 int형으로 넣어도 자동으로 wrapper 클래스로 감싸줌,