9장 Object 클래스, String 클래스, Math클래스

slee2·2021년 9월 10일
0

Java의 정석

목록 보기
17/28
post-thumbnail

Object 클래스

  • 모든 클래스의 최고 조상. 오직 11개의 메서드만을 가지고 있다.
  • notify(), wait() 등은 쓰레드와 관련된 메서드이다.
Object클래스의 메서드설명
protected void finalize()객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출된다.(마무리 작업이다.) 하지만, 메모리 부족 등으로 오류가 있을때 가비지 컬렉터에서 객체를 없애하는데 finalize가 실행되면서 시간이 오래걸려 거의 사용하지 않는다.
public boolean equals(Object obj)같으면 true. 객체 자신과 obj이 같은지 알려줌.
public String toString()문자열로 반환
protected Object clone()복사
public int hashCode()해시코드 반환
public Class getClass()객체의 클래스 정보(설계도 정보)를 Class인스턴스로 반환. 객체를 생성하거나 객체 정보를 얻을 수 있음(Hello.java -> Hello.class. Hello의 Class객체 생성.)

protected 붙은건 오버라이딩하여 public으로 변경해야함.

equals(Object obj)

  • 객체 자신(this)과 주어진 객체(obj)를 비교한다. 같으면 true 다르면 false.
  • Object클래스의 equals()는 객체의 주소를 비교(참조변수 값 비교)
public boolean equals(Object obj) {
	return (this==obj);	// 주소비교
}
class	Ex {
	public static void main(String[] args) {
   		Value v1 = new Value(10);
   		Value v2 = new Value(10);
      
   		System.out.println(v1.equals(v2));	// false. 주소 다름
   	}
}

true

false

hashCode()

  • 객체의 해시코드(hash code)를 반환하는 메서드
  • Object클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환
public class Object {
	...
   	public native int hashCode();

(native)네이티브 메서드 : OS가 가지고 있는 메서드(C언어로 작성되있는 경우가 많다)
이미 작성되있는 메서드를 호출하는 것이기 때문에 몸통({})이 없다. OS의 메서드가 객체의 주소를 int로 변환해서 반환해주는 형식. 객체마다 값이 달라서 객체 지문이라고 부르기도 한다.

  • equals()를 오버라이딩하면, hashCode()도 오버라이딩해야한다. equals()의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문이다.
  • System.identityHashCode(Object obj)는 Object클래스의 hashCode()와 동일. 객체마다 다른 해시코드를 반환하는 메서드.

-> 보통 equals와 hashCode를 오버라이딩을 했는데 객체의 해시코드값이 필요할때 identityhashcode를 사용한다.

public boolean equals(Object obj) {

        if (obj == null) {
            return false;
        }

        if (this.getClass() != obj.getClass()) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        Person that = (Person) obj;

        if (this.name == null && that.name != null) {
            return false;
        }

        if (this.id == that.id && this.name.equals(that.name)) {
            return true;
        }

        return false;
    }
@Override
public int hashCode() {

    final int prime = 31;
    int result = 1;

    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + id;

    return result;
}

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

  • toString() : 객체를 문자열(String)으로 변환하기 위한 메서드
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
   		설계도 객체  클래스이름     위치              16진수      객체주소
}

Card@1c655221

kind : 1 c : a

String 클래스

  • 문자열을 다루기 위한 클래스
  • String클래스 = 데이터(char[]) + 메서드(문자열 관련)
  • 내용을 변경할 수 없는 불변(immutable) 클래스
String	a = "a";
String	b = "b";
a = a + b;

  • 덧셈 연산자(+)를 이용한 문자열 결합은 성능이 떨어짐.
    -> 문자열의 결합이나 변경이 잦다면, 내용을 변경가능한 StringBuffer를 사용

문자열의 비교

  • String str = "abc"와 String str = new String("abc");의 비교
String	str1 = "abc";
String	str2 = "abc";
String	str3 = new String("abc");
String	str4 = new String("abc");	// 항상 새로운 문자열이 만들어짐


웬만하면 왼쪽으로 ㄱㄱ

문자열 리터럴

  • 문자열 리터럴은 프로그램 실행시 자동으로 생성된다.(constant pool(상수 저장소)에 저장)
    위에 그림에 문자열 리터럴에 관한 내용 있다 ㅎㅎ

빈 문자열("", empty string)

  • 내용이 없는 문자열. 크기가 0인 char형 배열을 저장하는 문자열
String	str = "";	// str을 빈 문자열로 초기화
  • 크기가 0인 배열을 생성하는 것은 어느 타입이나 가능
char[]	chArr = new char[0];	// 길이가 0인 char 배열
int[]	iArr = {};		// 길이가 0인 int 배열

C에서는 배열의 길이와 크기가 구분되있다. 예를들어서 int[10]에서 배열의 길이는 10이고 크기는 4byte x 10 = 40byte이다. 하지만 자바는 C처럼 메모리를 직접 다루지 않기 때문에 크기는 의미가 없다. 그래서 자바에서 배열의 길이와 크기는 같은 개념이다. 크기라는 말은 거의 안쓴다고 생각하면 될듯?

  • char와 String 초기화
------ 이 코드보다 ------
String s = null;
char c = '\u0000';
---- 이게 더 좋은 코드 ----
String s = ""
char c = ' ';

String 클래스의 생성자와 메서드(모음)

메서드/설명예제결과
String(String s)String s = new String("Hello")s = "Hello"
잘 안씀잘 안씀잘 안씀
String(char[] value)char[] c = {'H','e','l','l','o'};
String s = new String(c);
s = "Hello"
char를 String으로 바꿀때 쓴다반대로 하려면 tocharArray()를 쓴다그렇다
String(StringBuffer buf)StringBuffer를 String을 바꿀때 쓴다나중에 자세히
char charAt(int index)String s = "Hello"
char c = s.charAt(1);
c = 'e'
문자열의 인덱스에 있는 문자 반환그렇다그런것이다
int compareTo(String str)int i = "aaa".compareTo("aaa");
int i2 = "aaa".compareTo("bbb");
i = 0
i2 = -1
같으면 0왼쪽이 작으면 -1오른쪽이 작으면 1
String concat(String str)String s = "Hello";
String s2 = s.concat(" World");
s2 = "Hello World"
문자열 뒤에 붙이는거이게 필요할까모르겠군
boolean contains(CharSequence s)String s = "abcdefg";
boolean b = s.contain("bc");
b = true
오른쪽 값이 왼쪽값에 포함되어있는지확인하는것이다.
boolean endsWith(String suffix)String file = "Hello.txt";
boolean b = file.endsWith("txt")
b = true
suffix로 끝나는지 보는이다.
boolean equals(Object obj)String s = "Hello";
boolean b = s.equals("Hello");
boolean b2 = s.equalls("hello");
b = true
b2 = false
매개변수로 받은 문자열 (obf)과 String 인스턴스의 문자열을 비교한다.
boolean equalsIgnoreCase(String str)String s = "Hello";
bollean b = s.equalsIgnoreCase("heLLo");
b = true
대소문자 무시하고 비교한다...
int indexOf(int ch)String s = "Hello";
int idx1 = s.indexOf('o');
idx1 = 4
문자열이 몇번째 인덱스에 있는지알려줌아니 개많
int indexOf(int ch, int pos)String s = "Hello";
int idx1 = s.indexOf('e', 2);
idx1 = -1
pos인덱스부터 문자를 찾는다못찾았기 때문에-1반환
int indexOf(String str)String s = "ABCDEFG";
int idx = s.indexOf("CD");
idx = 2
문자열도 찾을 수 있다...
int lastIndexOf(int ch)String s = "java.lang.Object";
int idx1 = s.lastIndexOf('.');
idx1 = 9
뒤부터 찾는 것뒤부터 찾는 인덱스 값은 9.
int lastIndexOf(String str)String s = "java.lang.java";
int idx1 = s.lastIndexOf("java");
idx1 = 10
뒤부터 문자열을 비교한다...
int length()문자열 길이.
String[] split(String regex)String animals = "dog,cat,bear";
String[] arr = animals.split(",");
arr[0] = "dog"
arr[1] = "cat"
arr[2] = "bear"
아 스플릿아시는구나.
String[] split(String regex, int limit)String animals = "dog,cat,bear";
String[] arr = animals.split(",",2);
arr[0] = "dog"
arr[1] = "cat,bear"
몇개로 나눌지도 가능..
boolean startsWith(String prefix)String s = "java.lang.Object";
boolean b = s.startsWith("java");
boolean b2 = s.startsWith("lang");
b = true
b2 = false
prefix로 시작하는지 본다시작안하면 false.
String substring(int begin)
String substring(int begin, int end)
String s = "java.lang.Object";
String c = s.substring(10);
String p = s.substring(5, 9);
c = "Object"
p = "lang"
매개변수 하나만 쓴다면 begin부터 끝까지
두개면 begin부터 end까지 자른다.
..
String toLowerCase()
String toUpperCase()
소문자로
대문자로
.
String trim()String s = "   Hello World   ";
String s1 = s.trim();
s1 = "Hello World"
앞뒤 공백을 없애준다.가운데 공백은 안없어짐.
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
static String valueOf(Object o)
String b = String.valueOf(true);
String c = String.valueOf('a');
String i = String.valueOf(100);
String l = String.valueOf(100L);
String f = String.valueOf(10f);
String d = String.valueOf(10.0);
java.util.Date dd = new java.util.Date();
String date = String.valueOf(dd);
b = "true"
c = "a"
i = "100"
l = "100"
f = "10.0"
d = "10.0"
date = "Wed
Jan 27 21:26:
29 KST 2016"

CharSequence는 인터페이스이다. 각 String관련 클래스들이 공통 조상이 없기때문에 인터페이스로 CharSequence를 받아서 String관련 클래스들이 모두 들어갈 수 있도록 만든 것이다.
String 관련함수 : CharBuffer, Segment, String, StringBuffer, StringBuilder

join()과 StringJoiner

  • join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.
String animals = "dog,cat,bear";
String[] arr = animals.split(",");	// 문자열을 ','를 구분자로 배열에 저장
String str = String.join("-", arr);	// 배열의 문자열을 '-'로 구분해서 결합
System.out.println(str);		// dog-cat-bear

문자열과 기본형 간의 변환

  • 숫자를 문자열로
int i = 100;
String str1 = i + "";		// 편리하지만 느림.
String str2 = String.valueOf(i);	// 불편하지만 빠름.
  • 문자열을 숫자로
int	i = Integer.parseInt("100");	// old
int	i2 = Integer.valueOf("100");	// 위아래 방법 다 써도 되지만 클래스.valueOf가 통일되었기 때문에 이거 써라. 외우기 편함.

엄밀히 말하면 메서드가 참조변수를 반환하기 때문에 Integer i2이렇게 받는게 맞지만, 오토박싱이라는 기능이 참조변수 Integerint로 바꿔준다.

StringBuffer 클래스

  • String처럼 문자형 배열(char[])을 내부적으로 가지고 있다.
  • 그러나 String과 달리 내용을 변경할 수 있다.(mutable:가변(변경가능))
StringBuffer	sb = new StringBuffer("abc");
sb.append("123")	// sb의 내용 뒤에 "123"을 추가한다.

StringBuffer의 생성자

  • 배열은 길이 변경불가. 공간이 부족하면 새로운 배열 생성해야함
  1. 새로운 배열 생성
  2. 내용 복사
  3. 참조 변경
StringBuffer sb = new StringBuffer("abc");
sb.append("123");	// sb의 내용 뒤에 "123"을 추가한다.
StringBuffer sb2 = sb.append("ZZ");	// sb의 내용 뒤에 "ZZ"를 추가한다.
System.out.println(sb);	// abc123ZZ
System.out.println(sb2);	//abc123ZZ

-------- 더 간단히 --------
StringBuffer sb = new StringBUffer("abc");
sb.append("123").append("ZZ");
  • 위의 과정을 자주 거치게 되면 느려지고 양이 많아지므로 StringBuffer는 저장할 문자열의 길이를 고려해서 적절한 크기로 생성해야함
--- 적절한 크기를 지정하자 ---
public StringBuffer(int length) {
	value = new char[length];
   	shred = false;
}

--- 버퍼의 크기를 지정하지않으면 16으로 된다 ---
public StringBuffer() {
	this(16);
]

--- 지정한 문자열의 길이보다 16 더 크게 버퍼를 만든다 ---
public StringBuffer(String str) {
	this(std.length() + 16);
   	append(str);
}

StringBuffer의 비교

  • StringBuffer는 equals()가 오버라이딩되어있지 않다.(주소비교가 되버리는)
StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");

System.out.println(sb == sb2);	// false
System.out.println(sb.equals(sb2));	//false
  • 그래서 String으로 변환후에 equals()로 비교해야 한다.
String s = sb.toString();	// sb를 String으로 변환
String s2 = sb2.toString();

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

StringBuffer의 생성자와 메서드

메서드/설명예제/결과
StringBuffer()StringBuffer sb = new StringBuffer();
16길이의 인스턴스 생성sb = ""
StringBuffer(int length)StringBuffer sb = new StringBuffer(10);
길이만큼 문자 크기를 만들어 준다.sb = ""
StringBuffer(String str)StringBuffer sb = new StringBuffer("Hi");
str + 16을 갖는 인스턴스 생성sb = "Hi"
StringBuffer append(boolean b)
StringBuffer append(char c)
StringBuffer append(char[] str)
StringBuffer append(double d)
StringBuffer append(float f)
StringBuffer append(int i)
StringBuffer append(long l)
StringBuffer append(object obj)
StringBuffer append(String str)
String Buffer sb = new StringBuffer("abc");
StringBuffer sb2 = sb.append(true);
sb.append('d').append(10.0f);

StringBuffer sb3 = sb.append("ABC").append(123);
매개변수로 입력된 값을 문자열로 변환한 뒤 문자열 뒤에 덧붙인다.sb = "abctrued10.0ABC123"
sb2 = "abctrued10.0ABC123"
sb3 = "abctrued10.0ABC123"
int capactiry()StringBuffer sb = new StringBuffer(100);
sb.append("abcd");
int bufferSize = sb.capactiy();
int stringSize = sb.length();
StringBuffer인스턴스의 버퍼크기를 알려준다. length()는 버퍼에 담긴 문자열의 길이를 알려준다.bufferSize = 100
stringSize = 4(sb에 담긴 문자열이 "abcd"이므로)
char charAt(int index)StringBuffer sb = new StringBuffer("abc");
char c = sb.charAt(2);
인덱스 값의 문자 반환c = 'c'
StringBuffer delete(int start, int end)StringBuffer sb = new StringBuffer("0123456");
StringBuffer sb2 = sb.delete(3, 6);
시작위치부터 끝위치 사이에 있는 문자 삭제. 끝 위치 문자는 제외sb = "0126"
sb2 = "0126"
StringBuffer deleteCharAt(int index)StringBuffer sb = new StringBuffer("0123456");
sb.deleteCharAt(3);
인덱스 문자 제거sb = "0123456"
StringBuffer insert(boolean b)
StringBuffer insert(char c)
StringBuffer insert(char[] str)
StringBuffer insert(double d)
StringBuffer insert(float f)
StringBuffer insert(int i)
StringBuffer insert(long l)
StringBuffer insert(object obj)
StringBuffer insert(String str)
StringBuffer sb = new StringBuffer("0123456");
sb.insert(4, '.');
두번째 매개변수를 문자열로 변환하고 지정된 위치에 추가sb = "0123.456"
int length()StringBuffer sb = new StringBuffer("0123456");
int length = sb.length();
인스턴스에 저장된 문자열 길이length = 7
StringBuffer replace(int start, int end, String str)StringBuffer sb = new StringBuffer("0123456");
sb.replace(3, 6, "AB");
지정된 범위의 문자들을 str로 바꾼다.sb = "012AB6"
StringBuffer reverse()StringBuffer sb = new StringBuffer("0123456");
sb.reverse();
문자열 뒤집기sb = "6543210"
void setCharAt(int index, char ch)StringBuffer sb = new StringBuffer("0123456");
sb.setCharAt(5, 'o');
지정된 위치의 문자를 ch로 바꾼다.sb = "01234o6"
void setLength(int newLength)StringBuffer sb = new StringBuffer("0123456");
sb.setLength(5);

StringBuffer sb2 = new StringBuffer("0123456");
sb2.setLength(10);
String str = sb2.toString().trim();
지정된 길이로 문자열의 길이를 변경 빈공간은 널로 채워진다.sb = "01234"
sb2 = "0123456       "
str = "0123456"
String toString()StringBuffer sb = new StringBuffer("0123456");
String str = sb.toString();
인스턴스 문자열을 String으로 반환str = "0123456"
String substring(int start)
String substring(int start, int end)
StringBuffer sb = new StringBuffer("0123456");
String str = sb.substring(3);
String str2 = sb.substring(3, 5);
String을 뽑아서 반환. 시작만 쓰면 끝까지str = "3456"
str2 = "34"

StringBuilder

  • StringBuffer과 똑같으나 차이점이 있는데 StringBuffer는 동기화되어 있어 멀티 쓰레드에 안전하다. 반면 StringBuilder는 안되있음.
  • 멀티 쓰레드 프로그램이 아닌 경우, 동기화는 불필요한 성능저하 이럴 때는 StringBuffer 대신 StringBuilder를 사용해서 성능을 향상시킨다.

Math 클래스

  • 수학관련 static메서드의 집합
public static final double E = 2.718281284590452354;	// 자연로그의 밑
public static final double PI = 3.1415926535...;	// 원주율
  • roudn()로 원하는 소수점 아래 세 번째 자리에서 반올림하기
    1. 원래 값에 100을 곱한다.

    90.7552 * 100 -> 9075.52

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

    Math.round(9075.52) -> 9076

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

    9076 / 100.0 -> 90.76
    9076 / 100 -> 90

Math 클래스의 메서드

메서드/설명예제결과
static double abs(double a)
static float abs(double a)
static int abs(double a)
static long abs(double a)
int i = Math.abs(-10);
double d = Math.abs(-10.0);
i = 10
d = 10.0
주어진 값의 절대값을 반환한다.
static double ceil(double a)double d = Math.ceil(10.1);
double d2 = Math.ceil(-10.1);
double d3 = Math.ceil(10.000015);
d = 11.0
d2 = -10.0
d3 = 11.0
주어진 값을 올림하여 반환한다.
static double floor(double a)double d = Math.floor(10.8);
double d2 = Math.floor(-10.8);
d = 10.0
d2 = -11.0
주어진 값을 버림하여 반환한다.
static double max(double a, double b)
static float max(float a, float b)
static int max(int a, int b)
static long max(long a, long b)
double d = Math.max(9.5, 9.50001);
int i = Math.max(0, -1);
d = 9.50001
i = 0
주어진 두 값을 비교하여 큰 쪽을 반환한다.
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)
double d = Math.min(9.5, 9.50001);
int i = Math.min(0, -1);
d = 9.5
i = -1
주어진 두 값을 비교하여 작은 쪽을 반환
static double random()double d = Math.random();
int i = (int)(Math.random()*10) + 1
0.0 <= d < 1.0
1 <= i < 11
0.0~1.0범위의 임의의 double값을 반환
static double rint(double a)double d = Math.rint(1.2);
double d2 = Math.rint(2.6);
double d3 = Math.rint(3.5);
double d4 = Math.rint(4.5);
d = 1.0
d2 = 3.0
d3 = 4.0
d4 = 4.0
주어진 double값과 가장 가까우 정수값을 double형으로 반환한다. 단, 두 정수의 정가운데 있는 값(1.5, 2.5, 3.5 등)은 짝수를 반환별로 안쓴다 이거
static long round(double a)
static long round(float a)
long l = Math.round(1.2);
long l2 = Math.round(2.6);
long l3 = Math.round(3.5);
long l4 = Math.round(4.5);
double d = 90.7552;
double d2 = Math.round(d * 100)/100.0;
l = 1
l2 = 3
l3 = 4
l4 = 5
d = 90.7552
d2 = 90.76
소수점 첫째자리에서 반올림한 정수값(long)을 반환한다. 두 정수의 정가운데 있는 값은 항상 큰 정수를 반환.

0개의 댓글