Object클래스

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

- notify(), wait() 등은 쓰레드와 관련된 메소드이다.

 

equals(Object obj)

- 객체 자신(this)과 주어진 객체(obj)를 비교한다. 같으면 true 다르면 false.

- Object클래스의 equals()는 객체의 주소를 비교(참조변수 값 비교)

public boolean equals(Object obj) {
	return (this==obj);
}

 

ex)

class Value {
	int value;
	
	Value (int value) {
		this.value=value;
	}
	
	// Object의 equals()를 오버라이딩해서 주소가 아닌 value를 비교
	public boolean equals(Object obj) {	
//		return this==obj; // 서로 다른 객체의 주소비교는 항상 거짓이다. 
		// 참조변수의 형변환 전에는 반드시 instanceof로 확인해야함.
		if(!(obj instanceof Value)) return false;
		
		Value v = (Value)obj;	// obj를 value로 형변환
		
		return this.value==v.value;
	}
}

public class Ex9_1 {

	public static void main(String[] args) {
		Value v1 = new Value(10);
		Value v2 = new Value(10);
		
		System.out.println(v1.equals(v2));

	}

}

 

equals(Object obj)의 오버라이딩

- 인스턴스 변수(iv)의 값을 비교하도록 equals()를 오버라이딩해야 한다.

ex)

class Person {
	long id;

	public boolean equals(Object obj) {
		if(!(obj instanceof Person))
		  return false;
		
		return id ==((Person)obj).id;
	}
	
	Person(long id) {
		this.id = id;
	}
}

public class Ex9_2 {

	public static void main(String[] args) {
		Person p1 = new Person(8011081111222L);
		Person p2 = new Person(8011081111222L);
		
		if(p1.equals(p2))
			System.out.println("p1과 p2는 같은 사람입니다.");
		else
			System.out.println("p1과 p2는 다른 사람입니다.");

	}

}

 

 

hashCode()

- 객체의 해시코드(hash code)를 반환하는 메소드

- Object클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환

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

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

 

- System.identityHashCode(Object obj)Object클래스의 hashCode()와 동일

=> hashCode()를 오버라이딩 했을 경우, 기존의 hashCode가 필요할 때 사용하는 메소드

 

toString(), toString()의 오버라이딩

- toString() : 객체를 문자열(String)으로 변환하기 위한 메소드

public String toString() { // Objcet클래스의 toString()
	return getClass().getName()+“@”+Integer.toHexString(hashCode());
	}

 

(객체==iv집합 이므로 객체를 문자열로 변환한다는 것은 iv의 값을 문자열로 변환한다는 것과 같다.)

 

ex)

import java.util.Objects;

class Card {
	String kind;
	int number;
	
	Card() {
		this("SPADE", 1);
	}
	
	Card(String kind, int number) {
		this.kind=kind;
		this.number=number;
	}
	
	// equals()를 오버라이딩 하면 hashCode()도 일치하도록 오버라이딩 해야한다.
	public int hashCode() {
		return Objects.hash(kind, number);
	}
	
	public boolean equals(Object obj) {
		if(!(obj instanceof Card))
			return false;
		
		Card c = (Card)obj;
		return this.kind.equals(c.kind) && this.number==c.number;
	}
	// Object 클래스의 toString()을 오버라이딩
	public String toString() {
		return "kind : " + kind + ", number : " + number;
	}
}
public class Ex9_4 {

	public static void main(String[] args) {
		Card c1 = new Card();
		Card c2 = new Card();
		
		System.out.println(c1.equals(c2));
		
		System.out.println(new Card().toString());
		System.out.println(new Card().toString());
		
		System.out.println(c1.hashCode());
		System.out.println(c2.hashCode());
		
		
	}

}

* hashCode 오버라이딩 관련 참고 *

1) Objects 클래스는 객체와 관련된 유용한 메소드를 제공하는 유틸 클래스

2) int hash(Object... values) {...}

-> 매개변수가 가변인자(Object...)라서 호출시 지정하는 값의 개수가 정해져있지 않다.

 

String 클래스

- String 클래스 = 데이터(char[] - 문자배열) + 메소드(문자열 관련)

- 내용을 변경할 수 없는 불변(immutable) 클래스

 

String a = “a”;

String b = “b”;

a = a + b;

=> “ab” 라는 문자열이 아예 새로운 주소에 저장되고 a는 그 주소를 가리키게 된다.

 

- 덧셈 연산자(+)를 이용한 문자열 결합은 성능이 떨어짐.

문자열의 결합이나 변경이 잦다면, 내용을 변경가능한 StringBuffer를 사용 (내용변경 가능)

 

 

문자열의 비교

- String str = “abc”;String str = new String(“abc”);의 비교

 

String str1 = “abc”; // 문자열 리터럴 “abc“의 주소가 str1에 저장됨

String str2 = “abc”; // 문자열 리터럴 “abc“의 주소가 str2에 저장됨

String str3 = new String(“abc”); // 새로운 String 인스턴스를 생성

String str4 = new String(“abc”); // 새로운 String 인스턴스를 생성

 

문자열 리터럴

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

class Ex9_7 {
	public static void main(String args[]) {
	  String s1 = "AAA";
	  String s2 = "AAA";
	  String s3 = "AAA";
	  String s4 = "BBB";
	}
}

 

- 같은 내용의 문자열 리터럴은 하나만 만들어진다.

=> s1, s2, s3“AAA”의 주소를 같이 가리키게 된다.

 

빈 문자열 (“”, empty string)

- 내용이 없는 문자열. 크기가 0char형 배열을 저장하는 문자열

String str = “”; // str을 빈 문자열로 초기화

 

- 크기가 0인 배열을 생성하는 것은 어느 타입이나 가능

char[] chArr = new char[0]; // 길이가 0char배열

int[] iArr = {}; // 길이가 0int배열

 

- 문자(char)와 문자열(String)의 초기화

String s = “”; // 빈 문자열로 초기화

char c = ‘ ’; // 공백으로 초기화

 

 

String 클래스의 생성자와 메소드

 

 

 

join()StringJoiner

- join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.

String animals = "dog,cat,bear";
String[] arr = animals.split(","); // 문자열을 ‘,’를 구분자로 나눠서 배열에 저장
String str = String.join("-", arr); // 배열의 문자열을 ‘-’로 구분해서 결합
System.out.println(str);	// dog-cat-bear

* 많은 문자열을 결합할 때는 join이 더 효과적이다 *

 

문자열과 기본형 간의 변환

 

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

int i = 100;
String str1 = i + "";		// 방법1
String str2 = String.valueOf(i);  // 방법2

 

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

int i = Integer.parseInt("100"); // “100”을 100으로 변환하는 방법1
int i2 = Integer.valueOf("100"); // “100”을 100으로 변환하는 방법2

Integer i2 = Integer.valueOf("100"); // 원래는 반환 타입이 Integer

=> valueOf는 타입에 상관없이 쓸 수 있어서 편리함.

 

ex)

public class Ex9_10 {

	public static void main(String[] args) {
		int iVal = 100;
		String strVal = String.valueOf(iVal); // int를 String으로 변환하는 방법
		
		double dVal = 200.0;
		String strVal2 = dVal + ""; // double을 String으로 변환하는 또 다른 방법
		
		double sum = Integer.parseInt("+"+strVal) + Double.parseDouble(strVal2);
		// 문자열인 +가 있어도 숫자만 변환이 된다.
		
		double sum2 = Integer.valueOf(strVal) + Double.valueOf(strVal2);
		
		System.out.println(String.join("",strVal,"+",strVal2,"=")+sum);
		System.out.println(strVal+"+"+strVal2+"="+sum2);
	
	}

}

 

 

StringBuffer클래스

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

public final class StringBuffer implements java.io.Serializable {
	private char[] value;
	 ...
}

 

- 그러나 String과 달리 내용을 변경할 수 있다.(mutable)

StringBuffer sb = new StringBuffer(“abc”);

=> char 타입인 ‘a’ ‘b’ ‘c’로 저장이 된다.

 

sb.append(“123”); // sb의 내용 뒤에 “123”을 추가한다.

=> char 타입인 ‘a’ ‘b’ ‘c’ ‘1’ ‘2’ ‘3’ 이 저장 된다.

 
 

StringBuffer의 생성자

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

새로운 배열 생성

기존 내용을 복사

참조 변경

 

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

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

public StringBuffer() {
	this(16);		// 버퍼의 길이를 지정하지 않으면 버퍼의 길이는 16이 된다.
}

public StringBuffer(String str) {
  this(str.length() + 16);	// 지정한 문자열의 길이보다 16 더 길게 버퍼를 생성한다. 
  append(str); // 길이 3
}

 

StringBuffer의 변경

- StringBufferString과 달리 내용 변경이 가능하다.

StringBuffer sb = new StringBuffer("abc");
sb.append(“123”); // sb의 내용 뒤에 “123”을 추가한다.

(append() : 문자열 추가 / delete() : 삭제 / insert() : 삽입)

 

- append()는 지정된 내용을 StringBuffer에 추가 후, StringBuffer의 참조를 반환한다.

StringBuffer sb2 = sb.append("ZZ");
System.out.println(sb);  // abc123ZZ
System.out.println(sb2); // abc123ZZ

 

StringBuffer의 비교

- StringBufferequals()가 오버라이딩 되어있지 않다.

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");

System.out.println(sb==sb2);		// false
System.out.println(sb.equals(sb2));	// false

 

- StringBufferString으로 변환 후에 equals()로 비교해야 한다.

String s = sb.toString();
String s2 = sb2.toString();

System.out.println(s.equals(s2)); // true
 

StringBuffer의 생성자와 메소드

* 범위 설정의 경우, 시작 index는 포함이 되고 마지막 index는 포함이 되지 않는다.

 

ex)

public class Ex9_12 {

	public static void main(String[] args) {
		StringBuffer sb = new StringBuffer("01");
		StringBuffer sb2 = sb.append(23);
		sb.append('4').append(56);
		
		StringBuffer sb3 = sb.append(78);
		sb3.append(9.0);
		
		System.out.println("sb = "+sb);
		System.out.println("sb2 = "+sb2);
		System.out.println("sb3 = "+sb3);
		
		System.out.println("sb ="+sb.deleteCharAt(10));
		System.out.println("sb ="+sb.delete(3, 6));
		System.out.println("sb ="+sb.insert(3, "abc"));
		System.out.println("sb ="+sb.replace(6, sb.length(), "END"));
		System.out.println("capacity="+sb.capacity());
		System.out.println("length="+sb.length());
		
		
	}

}

 

 

StringBuilder (동기화x)

- StringBuffer는 동기화(데이터보호) 되어 있다. 멀티 쓰레드에 안전(thread-safe)

- 멀티 쓰레드 프로그램이 아닌 경우, 동기화는 불필요한 성능 저하

이럴 땐 StringBuffer대신 StringBuilder를 사용하면 성능 향상

(StringBufferStringBuilder로 바꿔주면 된다)

 

 

Math클래스

- 수학관련 static메소드의 집합

- round()로 원하는 소수점 아래 세 번째 자리에서 반올림하기

1. 원래 값에 100을 곱한다.

90.7552 * 100 -> 9075.52

2. 위의 결과에 Math.round()를 사용한다.

Math.round(9075.52) -> 9076

3. 위의 결과를 다시 100.0으로 나눈다.

9076 / 100.0 -> 90.76

 

* round()HALF_UP(0.5에서 무조건 올림), rint()round even(0.5에서 짝수로 만들 수 있을때만 올림)

 

ex)

public class RoundTest {

	public static void main(String[] args) {
		double sum = 0;
		double sum1 = 0;
		double sum2 = 0;
		
		for (double d = 1.5; d<=10.5; d++) {
			double d1 = Math.round(d);
			double d2 = Math.rint(d);
			
			System.out.printf("%4.1f %4.1f %4.1f%n", d, d1, d2);
			
			sum += d;
			sum1 += d1;
			sum2 += d2;
			
		}
		
		System.out.println("---------------");
		System.out.printf("%4.1f %4.1f %4.1f%n", sum, sum1, sum2);
		
		// d2의 sum 결과값이 원래값인 d의 sum과 일치함(일반 반올림보다 더 정확한 결과가 나옴)
	}

}

 

 

래퍼(wrapper) 클래스

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

public final class Integer extends Number implements Comparable {
	...
	private int value;
	...
}

 

 

Number클래스

- 모든 숫자 래퍼 클래스의 조상

(Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal의 조상)

public abstract class Number implements java.io.Serializable {
	public abstract int intValue();
	public abstract long longValue();
	public abstract float floatValue();
	public abstract double doubleValue();

	public byte byteValue() {
		return (byte)intValue();
	}
	
	public short ShortValue() {
		return (short)intValue();
	}
}

=> 보이는 것처럼, 래퍼 객체를 기본형으로 바꿔주는 메소드들이 있다.

 

문자열을 숫자로 변환하기

- 문자열을 숫자로 변환하는 다양한 방법

int i = new Integer(“100”).intValue();

int i2 = Integer.parseInt(“100”);

Integer i3 = Integer.valueOf(“100”); // 또는 Int i3 = Integer.valueOf(“100”);

 

* 또는 Byte b = new Byte(“100”); 처럼 생성자를 이용해서 문자열을 원하는 래퍼클래스로 변환 가능

 

- n진법의 문자열을 숫자로 변환하는 방법

int i4 = Integer.parseInt("100", 2); // 100(2) -> 4
		int i5 = Integer.parseInt("100", 8); // 100(8) -> 64
		int i6 = Integer.parseInt("100", 16); // 100(2) -> 256
		int i7 = Integer.parseInt("FF", 16); // 100(2) -> 255
//		int i8 = Integer.parseInt("FF"); // NumberFormatException 발생

 

 

오토박싱 & 언박싱 기본형과 참조형 간의 자동형변환

int -> (오토박싱) -> Integer 자동으로 해줌

int <- (언박싱) <- Integer

 

- JDK1.5 이전에는 기본형과 참조형간의 연산이 불가능했음

int i = 5;
Integer iObj = new Integer(7);

int sum = i + iObj;	// 에러, 기본형과 참조형 간의 덧셈 불가(JDK1.5 이전)

 

- 기본형의 값을 객체로 자동변환하는 것을 오토박싱, 그 반대는 언박싱

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);	// 오토박싱. 10 -> new Integer(10)

int value = list.get(0); // 언박싱. new Integer(10) -> 10

 

 

ex)

import java.util.ArrayList;

public class RoundTest2 {

	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<Integer>();	// ArrayList는 객체만 저장가능함
		list.add(new Integer(100)); // list에는 객체만 추가 가능
		list.add(100);	// JDK 1.5 이전에는 에러
		
//		Integer i = list.get(0); // list에 저장된 첫 번째 객체를 꺼낸다.
//		int i = list.get(0).intValue();	// intValue()로 Integer를 int로 변환
		
		int i = list.get(0);	// OK 
	}

}

 

 

ex)

 

public class Ex9_16 {

	public static void main(String[] args) {
		int i = 10;
		
		// 기본형을 참조형으로 형변환(형변환 생략가능)
		Integer intg = (Integer)i; // Integer intg = Integer.valueOf(i);
		Object obj = (Object)i;	// Object obj = (Object)Integer.valueOf(i);
		
		Long lng = 100L; 	// Long lng = new Long(100L);
		
		int i2 = intg + 10; // 참조형과 기본형간의 연산 가능
		long l = intg + lng; // 참조형 간의 덧셈도 가능
		
		Integer intg2 = new Integer(20);
		int i3 = (int)intg2; // 참조형을 기본형으로 형변환도 가능(형변환 생략가능)

	}

}

 


출처 - 유튜브 남궁성의 정석코딩 [자바의 정석 - 기초편] 

+ Recent posts