4. 자바기본 API(equals, wrapper클래스)

String

String 인스턴스 안에는 char 배열이 존재하는것이다.
String은 toString를 오버라이딩 하여 안에 내용이 출력된다.
toString를 오버라이딩 하여 인스턴스에 대한 정보를 확인할 수 있게 만드는 것은 좋은 습관이다. 디버깅할때 편하다는 장점이 있다.

equals

결과를 예측해보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

public class EqualsTest {
public static void main(String[] args) {
Point point1 = new Point(10, 20);
Point point2 = new Point(10, 20);
Point point3 = point2;

// ==연산자에서 두 개의 항이 객체 참조 변수 인 경우
// 두 개체의 동일 여부(동일성)
System.out.println( point1 == point2 ); //false
System.out.println( point2 == point3 ); //true

//equals는 오버라이딩이 되지 않았을 경우 참조값 비교를 함.(동질성 비교)
//해쉬코드를 갖고와서 비교를함(해쉬코드==참조값)
System.out.println( point1.equals(point2) ); //false
System.out.println( point2.equals(point3) ); //true

System.out.println("================");

//String 객체와 비교
//String는 equals가 오버라이딩 되어있다.
String s1 = new String( "hello" );
String s2 = new String( "hello" );
String s3 = s2;

System.out.println( s1 == s2 ); //false
System.out.println( s2 == s3 ); //true
System.out.println( s1.equals(s2) ); //true
System.out.println( s2.equals(s3) ); //true

}
equals를 오버라이딩 해보자

hashCode()메소드도 오버라이딩이 필요하다.
자바에서는 hashCode() equal() 메소드를 동시에 오버라이드 해야한다.
equals 조건을 제곱으로 한다면 hashCode도 제곱으로 변경해주어야 한다.
그렇지 않으면 해쉬맵 해쉬 셋을 쓸 때 어려워진다.

Point.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Point {
private int x;
private int y;

..

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Point other = (Point) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
결과를 예측해보자
1
2
3
4
5
6
7
8
9
10
// String Literal		
// 문자열 상수 Pool에 있는것을 재사용함
// 문자열 상수 Pool을 공유하기 때문에 문자열의 수정이 불가능하다.
// str1의 변경은 가능하나 문자열 상수인 hello의 값이 변경 불가능하다는것.
String str1 = "hello";
String str2 = "hello";
String str3 = str2;

System.out.println( str1 == str2 ); //true
System.out.println( str2 == str3 ); //true
new String(“문자열”) “문자열”의 차이는?

위의 결과를 보고 잘 생각해 보자
문자열은 변경되지 않는다는점을 잘 생각하자.
변한다면 참고하고 있는 다른 참조변수들이 피해를 본다..

잘생각해보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
String str1 = "abc";
String str2 = "cde";
String str3 = str2;

str2 = str3.toUpperCase();

System.out.println(str1);
System.out.println(str2);
System.out.println(str3);

String str4 = str2.concat("??");
System.out.println(str2);
System.out.println(str4);

// String s = "!";
// String str5 = s.concat(str2);
// Method chain
String str5 = "!".concat(str2); //위의 코드와 별다른 차이가 없다.

System.out.println(str5);
}

String 메소드의 사용법 및 활용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class StringTest03 {

public static void main(String[] args) {
String s= "abcAbcabcABC";

//charAt
char c = s.charAt( 2 );
System.out.println( c );

//indexOf
System.out.println( s.indexOf( "Abc" ) ); //3
System.out.println( s.indexOf("ab") ); //0
System.out.println( s.lastIndexOf("ab") ); //6
System.out.println( s.indexOf( "XYZ" )); //-1 반환

//replace
System.out.println( s.replace("bc", "12") ); //s가 바뀌지는 않음
System.out.println( s.replaceAll("bc", "12") ); //s가 바뀌지는 않음

//substring
System.out.println( s.substring( 3, 7) ); //3~6까지 나온다

//case
System.out.println( s.toLowerCase() );
System.out.println( s.toUpperCase() );

//concat
String str1 = " ab cd ";
String str2 = ",efg";

str1 = str1.concat(str2);


//trim
System.out.println( "---" + str1 + "---" ); //--- ab cd ,efg---
System.out.println( "---" + str1.trim() + "---" );//---ab cd ,efg---

//split
String[] tokens = str1.split(",");
for( String token : tokens) { // ab cd
System.out.println( token ); // efg
}

//split 예외
tokens = "abcdefg".split( "," );
for( String token : tokens) {
System.out.println( token ); //abcdefg
}

tokens = "".split( "," );
System.out.println( tokens.length ); // 1

}
}

StringBuffer

StringBuffer는 가변크기의 버퍼를 가짐.
“abc” + “cde” (String) 보다는 StringBuffer를 쓰는게 낫다.
전자의 경우 런타임 때 “abc”를 스트링 버퍼로 만들고 append(“cde”)후 toString()를 통해 값을 반환한다.
String를 사용해도 되지만 append의 작업이 많을 경우 StringBuffer사용하는것이 빠르다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static void main(String[] args) {
//생성
StringBuffer sb = new StringBuffer( "this" );

System.out.println(sb.length() + ":" + sb.capacity()); //4:20
//버퍼의 크기를 문자의 크기보다 크게 생성함(append를 염두)

//문자열추가
sb.append(" is pencil");
System.out.println( sb );

//삽입
sb.insert(7, " my");
System.out.println( sb ); //this is my pencil

//치환
sb.replace( 8, 10, "your" );
System.out.println( sb );

//버퍼 크기
sb.setLength( 3 );
System.out.println( sb );

//문자열 + 연산은 내부적으로 StringBuffer 객체로 변환
String s1 = "Hello" + " World" + 10 +true;
System.out.println(s1); //Hello World10true
//다음과 코드가 같은것.

String s2 = new StringBuffer( "Hello" ).append( " World" ).append( 10 ).append( true ).toString();

System.out.println(s1); //Hello World10true
System.out.println(s2); //Hello World10true
}

Wrapper 클래스

기본형 보다는 Wrapper 클래스를 쓰고자하는 움직임이 많이 발생하고 있다.

WrapperClassTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class WrapperClassTest {
public static void main(String[] args) {
Integer i = new Integer(10);
Character c = new Character( 'c' );
Float f = new Float ( 3.14 );
Boolean b = new Boolean( true );

//Auto Boxing
Integer j = 10;


//int k = 20 + j.intValue();
//Auto Unboxing
int k = 20 + j;
}

public static void swap( Integer a, Integer b ) {
// 상수풀 운영원칙 때문에 객체이지만 내부를 수정할 수 없다.
}
}
정규식을활용하여 정수인지 확인
WrapperClassTest2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class WrapperClassTest2 {
public static void main(String[] args) {
System.out.println( Character.toLowerCase( 'a' ));
System.out.println( Character.isDigit( '1' ));
System.out.println( Character.isDigit( '@' ));

//String는 isdigit가 존재하지 않는다.
String s = "1234";
if(s.matches("-?\\d+") == false ) {
System.out.println("숫자가 아닙니다");
} else {
int i = Integer.parseInt(s);
}

// 프로그램 로직(변수 검증) 할 때는
// try - catch 문으로 하지 말것.
// 비용이 많이든다.

//정규식을 활용하자
}
}

Share