공부/Java

[Java-09] java.lang패키지 - StringBuffer클래스, Math클래스, Wrapper클래스

줭♪(´▽`) 2021. 3. 9. 12:16

1. StringBuffer클래스

- String클래스와 달리 인스턴스를 생성할 때 지정된 문자열을 변경할 수 있음

- 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있음

 

1) StrigBuffer의 생성자

- StringBuffer클래스의 인스턴스를 생성할 때 적절한 길이의 char형 배열이 생성, 이는 문자열을 저장하고 편집하기 위한 공간(buffer)으로 사용됨

- 버퍼의 길이를 지정해주는 StringBuffer(int length)를 사용하여 충분히 여유있는 크기의 버퍼를 생성하는 것이 좋음

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);
}

 

- 만약, 문자열이 버퍼의 크기보다 클 때는 내부적으로 버퍼의 크기를 증가시키는 작업이 수행됨

// 새로운 길이의 배열 생성
// newCapacity는 정수값
char[] newValue = new char[newCapacity];

// 배열 value의 내용을 배열 newValue로 복사
System.arraycopy(value, 0, newValue, 0, count);	// count는 문자열의 길이
value = newValue;

 

- StringBuffer클래스의 생성자

 

생성자 예 제 결 과
StringBuffer() StringBuffer sb = new StringBuffer(); sb = ""
16문자를 담을 수 있는 버퍼를 가진 StringBuffer 인스턴스 생성
StringBuffer(int length) StringBuffer sb = new StringBuffer(10); sb = ""
지정된 개수(length)의 문자를 담을 수 있는 버퍼를 가진 StringBuffer 인스턴스 생성
StringBuffer(String str) StringBuffer sb = new StringBuffer("Hi"); sb = "Hi"
지정된 문자열 값(str)을 갖는 StringBuffer 인스턴스 생성

 

2) StringBuffer의 변경

- String과 달리 StringBuffer는 내용을 변경할 수 있음

- append()의 반환타입은 StringBuffer이며, 자신의 주소를 반환

- append()는 연속적으로 호출이 가능함 (하나의 인스턴스에 대하여)

 

3) StringBuffer의 비교

- String과 달리 StringBuffer에서는 equals메서드를 오버라이딩하지 않음

- 즉, equals메서드와 등가비교연산자(==)는 같은 결과를 얻음

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

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

 

- toString()은 오버라이딩되어 있기 때문에 담고있는 문자열을 String으로 반환함

- 따라서 StringBuffer인스턴스의 문자열을 비교하기 위해서는 toString()을 호출하여 String인스턴스를 얻은 후, equals메서드를 사용하여 비교해야 함

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

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

 

4) StringBuffer클래스의 메서드

 

메서드 예 제 결 과
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)
StringBuffer 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"
매개변수로 입력된 값을 문자열로 변환하여 StringBuffer인스턴스가 저장하고 있는 문자열의 뒤에 덧붙임
int capacity() StringBuffer sb = new StringBuffer(100);
sb.append("abcd");
int bufferSize = sb.capacity();
int stringSize = sb.length();
bufferSize = 100
stringSize = 4
StringBuffer인스턴스의 버퍼크기를 알려줌 (length()는 문자열의 길이)
char charAt(int index) StringBuffer sb = new StringBuffer("abc");
char c = sb.charAt(2);
c = 'c'
지정된 위치(index)에 있는 문자 반환
StringBuffer delete(int start, int end) StringBuffer sb = new StringBuffer("0123456");
StringBuffer sb2 = sb.delete(3, 6);
sb = "0126"
sb2 = "0126"
시작위치(start)부터 끝 위치(end) 사이에 있는 문자 제거 (단, 끝 위치의 문자는 제외)
StringBuffer deleteCharAt(int index) StringBuffer sb = new StringBuffer("0123456");
sb.deleteCharAt(3);
sb = "012456"
지정된 위치(index)의 문자 제거
StringBuffer insert(int pos, boolean b)
StringBuffer insert(int pos, char c)
StringBuffer insert(int pos, char[] str)
StringBuffer insert(int pos, double d)
StringBuffer insert(int pos, float f)
StringBuffer insert(int pos, int i)
StringBuffer insert(int pos, long l)
StringBuffer insert(int pos, Object obj)
StringBuffer insert(int pos, String str)
StringBuffer sb = new StringBuffer("0123456");
sb.insert(4, '.');
sb = "0123.456"
두 번째 매개변수로 받은 값을 문자열로 변환하여 지정된(pos)에 추가
pos는 0부터 시작
int length() StringBuffer sb = new StringBuffer("0123456");
int length = sb.length();
length = 7
StringBuffer인스턴스에 저장되어 있는 문자열의 길이 반환
StringBuffer replace(int start, int end, String str) StringBuffer sb = new StringBuffer("0123456");
sb.replace(3, 6, "AB");
sb = "012AB6"
지정된 범위(start~end)의 문자들을 주어진 문자열로 바꿈 (단, 끝 위치의 문자는 제외)
StringBuffer reverse() StringBuffer sb = new StringBuffer("0123456");
sb.reverse();
sb = "6543210"
StringBuffer인스턴스에 저장된 문자열의 순서를 거꾸로 나열
void setCharAt(int index, char ch) StringBuffer sb = new StringBuffer("0123456");
sb.setCharAt(5, 'o');
sb = "01234o6"
지정된 위치의 문자를 주어진 문자(ch)로 바꿈
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"
지정된 길이의 문자열의 길이를 변경. 길이를 늘리는 경우에 나머지 빈 공간을 널문자 '\u0000'로 채움
String toString() StringBuffer sb = new StringBuffer("0123456");
String str = sb.toString();
str = "0123456"
StringBuffer인스턴스의 문자열을 String으로 반환
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);
str = "3456"
str2 = "34"
지정된 범위 내의 문자열을 String으로 뽑아서 반환
시작위치(start)만 지정하면 시작위치부터 문자열 끝까지 뽑아서 반환
끝 위치(end)는 포함되지 않음

 

5) StringBuilder클래스

- StringBuffer는 멀티쓰레드에 안전(thread safe)하도록 동기화되어 있음

- 멀티쓰레드로 작성된 프로그램이 아닌 경우, StringBuffer의 동기화는 불필요하게 성능만 떨어뜨림

- 그래서 StringBuffer에서 쓰레드의 동기화만 뺀 StringBuilder가 새로 추가됨

- StringBuilder는 StringBuffer와 완전히 똑같은 기능으로 작성되어 있음

- 성능 향상이 반드시 필요한 경우를 제외하고는 굳이 StringBuilder로 바꿀 필요 없음

StringBuilder sb;
sb = new StringBuilder();
sb.append("abc");

// StringBuffer와 동일한 기능

 


 

2. Math 클래스

- 기본적인 수학계산에 유용한 메서드로 구성

- 모든 메서드는 static이며, 2개의 상수가 정의되어 있음

 

① 자연로그의 밑

public static final double E = 2.7182818284590452354;

 

② 원주율

public static final double PI = 3.14159265358979323846;

 

1) Math클래스의 메서드

 

메서드 예 제 결 과
static double abs(double a)
static float abs(float f)
static int abs(int f)
static long abs(log f)
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.500001);
int i = Math.max(0, -1);
d = 9.500001
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.500001);
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값 반환 (단, 1.0은 범위에 포함되지 않음)
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 = -3
l4 = 5
d = 90.7552
d2 = 90.76
소수점 첫째자리에서 반올림한 정수값(long) 반환
매개변수의 값이 음수인 경우, round()와 rint()의 결과가 다름

 

2) 올림, 내림, 반올림

- round()는 항상 소수점 첫째자리에서 반올림하여 정수값(long)을 반환

- 원하는 자리에서 반올림된 값 얻는 법

① 10의 n제곱을 곱함

② Math.round() 사용

③ (10의 n제곱).0으로 나눔

// 소수점 셋째자리에서 반올림 하는 법
90.7552 * 100 = 9075.52
Math.round(9075.52) = 9076
9076 / 100.0 = 90.76

 

3) 예외를 발생시키는 메서드

- 이름에 'Exact'가 포함된 메서드들은 정수형간의 연산에서 발생할 수 있는 오버플로우를 감지하는 메서드임

- 오버플로우가 발생하면 예외(ArithmeticException)를 발생

int addExact(int x, int y)			// x + y
int subtractExact(int x, int y)			// x - y
int multiplyExact(int x, int y)			// x * y
int incrementExact(int a)			// a++
int decrementExact(int a)			// a--
int negateExact(int a)				// -a
int toIntExact(long value)			// (int)value

 

 


 

3. 래퍼(Wrapper)클래스

- 기본형(primitive type) 값들을 객체로 다루는 클래스

- 객체생성 시에 생성자의 인자로 주어진 각 자료형에 알맞은 값을 내부적으로 저장하고 있음

 

- 모두 equals()가 오버라이딩되어 있어 객체의 값을 가지고 비교함

- 비교연산자를 사용하고 싶으면 compareTo()를 사용

 

- 모두 toString()이 오버라이딩되어 있음

 

1) Wrapper클래스의 생성자

 

기본형 래퍼클래스 생성자 활용 예
boolean Boolean Boolean(boolean value)
Boolean(String s)
Boolean b = new Boolean(true);
Boolean b2 = new Boolean("true");
char Character Character(char value) Character c = new Character('a');
byte Byte Byte(byte value)
Byte(String s)
Byte b = new Byte(10);
Byte b2 = new Byte("10");
short Short Short(short value)
Short(String s)
Short s = new Short(10);
Short s = new Short("10");
int Integer Integer(int value)
Integer(String s)
Integer i = new Integer(100);
Integer i2 = new Integer("100");
long Long Long(long value)
Long(String s)
Long l = new Long(100);
Long l2 = new Long("100");
float Float Float(double value)
Float(float value)
Float(String s)
Float f = new Float(1.0);
Float f2 = new Float(1.0f);
Float f3 = new Float("1.0f");
double Double Double(double value)
Double(String s)
Double d = new Double(1.0);
Double d = new Double("1.0");

 

2) Number클래스

- 추상클래스로, 내부적으로 숫자를 멤버변수로 갖는 래퍼 클래스들의 조상

래퍼 클래스의 상속계층도

 

 

3) 오토박싱(Autoboxing) & 언박싱(Unboxing)

- JDK1.5 이전에는 기본형과 참조형 간의 연산이 불가능했기 때문에, 래퍼 클래스로 기본형을 객체로 만들어서 연산해야 했음

- JDK1.5 이후에는 컴파일러가 자동으로 변환해주어 기본형과 참조형 간의 연산이 가능함

- 자바의 문법이 바뀐 것이 아니고, 컴파일러가 제공하는 편리한 기능임

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

// 컴파일 전
int sum = i + iObj;

// 컴파일 후
int sum = i + iObj.intValue();

 

- 오토박싱(autoboxing) : 기본형 값을 래퍼 클래스의 객체로 자동으로 변환해주는 것

- 언박싱(unboxing) : 래퍼 클래스의 객체를 기본형 값으로 자동으로 변환해주는 것

ArrayList<Integer> list = new ArrayList<Integer>();

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

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

 

 

 

 

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)