-
[Java]STEP1 - 21) Wrapper(포장) 클래스, Math 클래스, Random 클래스개발 공부/Java 2020. 10. 18. 18:23
본 게시글은 도서 "이것이 자바다" 동영상 강의를 듣고 기록하는 TIL(Today I Learned) 입니다.
모든 저작권은 출판사 한빛미디어와 신용권님께 있음을 알립니다.👍이번 게시물에서는 Wrapper 클래스, Math 클래스, Random 클래스에 대해서 알아보겠습니다.
1. Wrapper(포장) 클래스
자바는 기본 타입(byte, char, short, int, long, float, double, boolean)의 값을 갖는 객체를 생성할 수 있는데, 이런 객체를 포장(Wrapper) 객체라고 한다.
포장 클래스는 java.lang 패키지에 포함되어 있고 기본 타입에 대응되는 클래스들은 다음과 같다.
1) byte : Byte
2) char : Character
3) short : Short
4) int : Integer
5) long : Long
6) float : Float
7) double : Double
8) boolean : Boolean
[박싱(Boxing)과 언박싱(Unboxing)]
박싱(Boxing): 기본 타입의 값을 포장 객체로 만드는 과정
언박싱(Unboxing): 포장 객체에서 기본 타입의 값을 얻어내는 과정
박싱을 하는 방법은 두 가지가 있다.
1) 생성자를 이용
Byte obj = new Byte(10);
Byte 타입의 Wrapper 객체를 생성하여 생성자의 매개값으로 10을 주었다.
Byte obj = new Byte("10");
Byte 타입의 Wrapper 객체를 생성하여 생성자의 매개값으로 문자열 "10"을 주었다.
매개값으로 들어간 문자열을 알아서 인식하여 byte 타입의 정수 10으로 Byte 객체가 받아들인다.2) valueOf() 메소드를 이용
Integer obj = Integer.valueOf(1000);
Integer 타입의 Wrapper 객체를 생성하여 valueOf() 메소드의 매개값으로 1000을 주었다.
Integer obj = Integer.valueOf("1000");
Integer 타입의 Wrapper 객체를 생성하여 valueOf() 메소드의 매개값으로 문자열 "1000"을 주었다.
valueOf() 메소드의 매개값으로 문자열을 주어도 알아서 인식하여 int 타입의 정수 1000으로 Integer 객체가 받아들인다.언박싱을 하는 방법은 다음과 같다.
int number = obj.intValue();
byte, char, short, int, long, float, double, boolean 기본 타입 모두 위와 같이 선언하여 언박싱 할 수 있다.
"타입 변수이름 = 객체.타입Value();" 와 같은 형태로 작성하면 된다.
number 라는 int 타입의 변수에는 Integer 객체 obj에 들어있는 정수 value가 들어간다.직접 박싱, 언박싱 하지 않아도 자동 박싱, 자동 언박싱이 일어나는 경우도 있다.
<자동 박싱>
Integer obj = 100;
obj는 Integer 타입의 객체이고, 100은 int 타입의 정수이다.
따라서 원래라면 서로 타입이 다르기 때문에 위와 같은 코드는 예외가 발생하겠지만
자바 5부터는 위와 같이 작성해도 자동적으로 박싱이 일어나기 때문에 예외가 발생하지 않는다.
<자동 언박싱>
Integer obj = new Integer(100);
int value = obj;
value는 int 타입의 변수이고, obj는 Integer 타입의 객체이다.
따라서 원래라면 서로 타입이 다르기 때문에 예외가 발생하지만,
자바 5부터 자동적으로 언박싱이 일어나기 때문에 예외가 발생하지 않는다.문자열을 기본 타입 값으로 변환할 때는 parseInt(); 와 같은 메소드를 이용하면 된다.
int number = Integer.parseInt("2516");
parseInt() 메소드는 문자열을 매개값으로 받아서 int 타입의 정수로 변환해준다.
byte, short, int, long, float, double, boolean도 parse + 타입 메소드가 있으므로 적절히 사용할 수 있다.포장 객체 내부의 값을 비교하기 위해 ==나 !=를 사용할 수 없다.
그 이유는 객체끼리 ==나 != 비교를 할 경우에는, 내부의 값이 아니라 그 객체의 주소 값을 기준으로 비교하기 때문이다.
물론 예외는 있다.
타입 값의 범위 boolean true, false char \u0000 ~ \u007f byte, short, int -128 ~ 127 위 표와 같은 범위는 포장 객체라고 하더라도 ==와 !=를 사용하여 내부의 값을 비교할 수 있다.
하지만 포장 객체에 어떤 값이 들어갈지 확실하지 않는 상황이라면 ==나 !=는 사용하지 않는 것이 바람직하다.
그러므로 포장 객체를 비교할 때는
1) 내부 값을 언박싱하여 변수에 넣은 후 변수를 비교
2) equals() 메소드를 이용해서 내부 값을 비교
와 같이 둘 중 하나를 이용해서 비교하는 것이 좋다.
2. Math 클래스
java.lang.Math 클래스는 수학 계산에 사용할 수 있는 메소드를 제공한다.
리턴타입 메소드 사용 int, double abs(number) number의 절대값을 반환한다. (양수와 0은 그대로, 음수는 양수로) double ceil(number) 실수의 올림 값을 반환한다. (5.3은 6.0으로 반환) double floor(number) 실수의 버림 값을 반환한다. (5.3은 5.0으로 반환) int, double max(num1, num2) num1과 num2 중 큰 값을 반환한다. int, double min(num1, num2) num1과 num2 중 작은 값을 반환한다. double random() 0.0 이상 1.0 미만의 실수 중 랜덤하게 하나를 반환한다. (0.0 <= X < 1.0) double rint(number) number에서 가까운 정수의 실수 값을 반환한다. (5.3이라면 5.0을, 5.7이라면 6.0을 반환) long round(number) 실수의 반올림 값을 반환한다. (5.1이라면 5.0을, 5.9라면 6.0을 반환) round() 메소드는 항상 소수점 첫째 자리에서 반올림하여 정수값을 리턴한다.
만약, 첫째 자리가 아니라 별도로 원하는 소수점 자리에서 반올림 값을 얻으려면
반올림할 자릿수가 소수점 첫째 자리가 되도록 10^n을 곱한 후, round() 메소드의 리턴값을 얻는다.
그 다음 다시 10^n.0을 나눠주면 된다.
double value = 12.3456;
double temp1 = value * 100;
long temp2 = Math.round(temp1);
double result = temp2 / 100.0;
result는 12.35가 나온다.
12.3456을 소수점 셋째 자리에서 반올림을 하려면 위 코드처럼 작성하면 된다.
12.3456에 100을 먼저 곱한다. 그럼 1234.56이 된다.
그 다음 round() 메소드를 적용한다. 소수점 첫째 자리에서 반올림 하므로 1235가 된다.
그리고 다시 100.0으로 나눈다. 그럼 result 값이 12.35가 된다.random() 메소드는 0.0과 1.0 사이의 범위에 속하는 하나의 double 타입의 난수를 리턴한다.
만약 0.0과 1.0사이가 아니라, 사용자가 원하는 임의의 범위 내의 난수를 리턴하려면 다음과 같은 처리가 필요하다.
int number = (int) (Math.random() * 10);
이것은 0이상 10미만의 난수 한 개를 정수형으로 반환하는 코드이다.
원래 Math.random()이 0.0 <= X < 1.0 이었기 때문에 여기에 10을 곱해주면
0.0 <= X < 10.0 이 된다. 즉 0.0에서부터 10.0 미만의 난수 한 개를 반환하는 것이다.
따라서 0이상 n미만의 난수 한 개를 정수형으로 반환하는 코드는 다음과 같다.
int number = (int) (Math.random() * n);
만약 0이상이 아니라, m이상 m+n미만의 난수 한 개를 정수형으로 반환하고자 한다면
int number = (int) (Math.random() * n) + m; 의 형태로 작성하면 된다.
이런 방식으로 사용자가 원하는 임의의 범위 내의 난수를 반환할 수 있다.
3. Random 클래스
Math.random() 메소드 이외에, Random 클래스를 이용해서 난수를 반환할 수도 있다.
java.util.Random 클래스에서는 난수를 얻어내기 위한 다양한 메소드를 제공한다.
Math.random()에서는 0.0이상 1.0미만의 난수를 얻었지만
Random 클래스에서는 boolean, int, long, float, double의 난수를 바로 얻을 수 있다.
또한 종자값(seed)라는 개념이 등장하는데, 종자값은 난수를 만드는 알고리즘에 사용되는 값으로 종자값이 같으면 같은 난수를 얻는다.
Random 클래스로부터 Random 객체를 생성하는 법은 다음과 같이 두 가지가 있다.
1) Random() : 호출 시 마다 다른 종자값(현재 시간)이 자동 설정된다.
2) Random(long seed) : 매개값으로 주어진 종자값이 설정된다.Random 클래스가 제공하는 메소드는 다음과 같다.
리턴타입 메소드(매개변수) 사용 boolean nextBoolean() boolean 타입의 난수를 리턴 double nextDouble() double 타입의 난수를 리턴 (0.0이상 1.0 미만) int nextInt() int 타입의 난수를 리턴(int의 가능 범위 중) int nextInt(int n) int 타입의 난수를 리턴(0이상 n 미만) Random random = new Random();
int number1 = random.nextInt(10) + 1;
random = new Random(5);
int number2 = random.nextInt(10) + 1;
random.nextInt(10) 은 0이상 10미만의 난수를 리턴한다.
+1을 해줌으로써 1이상 10이하의 난수를 리턴하게 된다.
Random 객체는 처음에는 생성자에 매개값이 없고, 그 다음에는 종자값 5가 들어가게되었다.
그러므로 number1은 현재 시간을 종자값으로 난수가 형성되고
number2는 5를 종자값으로 난수가 형성된다.
만약 위 코드 다음에 아래 number3가 추가적으로 온다면
random = new Random(5);
int number3 = random.nextInt(10) + 1;
종자값이 5로 같기 때문에 number3는 number2와 동일한 값을 리턴할 것이다.본 게시글은 여기서 마치겠습니다.
읽어주셔서 감사하고, 혹시나 틀린 부분이나 보완해야할 부분이 있다면 댓글에 남겨주세요~!
'개발 공부 > Java' 카테고리의 다른 글
[Java]STEP2 - 1) 제네릭(Generic)이란?, 제네릭의 등장 배경과 필요성 (0) 2020.11.24 [Java]STEP1 - 22) Date 클래스, Calendar 클래스, Format 클래스 (0) 2020.10.19 [Java]STEP1 - 20) Arrays 클래스 (0) 2020.10.17 [Java]STEP1 - 19) 정규 표현식과 Pattern 클래스 (0) 2020.10.17 [Java]STEP1 - 18) String 클래스, StringTokenizer, StringBuffer, StringBuilder (0) 2020.10.16