생각을 개발하자, 박진형

[Java] 표준 API #4 - Arrays, Wrapper, Math, Random 본문

Java/java basic

[Java] 표준 API #4 - Arrays, Wrapper, Math, Random

imjinbro imjinbro 2017.10.12 02:43

[src github repo]

https://github.com/imjinbro/javaBasic



[API 소개
]

1) java.util.Arrays

- 배열 수정과 관련한 메서드를 제공하는 유틸리티 클래스 : 모두 static 메서드

- 알고리즘 공부할 기본적으로 Arrays 제공하는 메서드를 만들어보는 것도 좋은

=> Arrays만이 아니라 util 있는 것을 똑같이 구현해보는 것도 공부많이될


- 레퍼런스 타입 비교 기준 : java.util.Comparable 구현 클래스 - 메서드 오버라이딩(오름, 내림차순 코딩)

=> Arrays.binarySearch Comparable 변수 타입 표준화, compareTo 사용함 : Arrays.

=> Arrays.binarySearch 사용하지않거나 레퍼런스 타입 특정 필드 쏘팅(기준까지) + 써치한다면 아래처럼

(1) Array 아니라면 쏘팅 기준 : java.util.Comparator 구현해서 쏘팅 기준 정의

(2) 커스텀 쏘팅 메서드

(3) 커스텀 써치 메서드

import java.util.Arrays;
import java.util.Comparator;

public class ArraysTest {
public static void main(String[] args) {
int[] numArr = {1,2,3,4,5};

//copyOf : 지정 크기만큼 배열 복사, 원래 배열보다 더 커도됨, 내부적으로는 System.arraycopy()
int[] newArr = Arrays.copyOf(numArr, 10);
for(int i : newArr){
System.out.println(i);
}
//System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);


//copyOfRange : 지정 인덱스 n ~ m까지 배열 복사
newArr = Arrays.copyOfRange(numArr, 0, 5);
for(int i : newArr){
System.out.println(i);
}


/*
deepEquals : 참조형 타입 배열 비교할 때 사용
1) reference type 요소 비교
2) 같은 Object[]를 참조하고있다면 바로 true
3) 길이가 다르거나 한쪽이 null 일 경우 바로 false
4) 길이가 같고 두 쪽다 null이 아닐 경우 Object 요소 같은 주소값인지 비교 후 결과
*/
//primitive type과 Wrapper 인스턴스 차이
Integer[] arr1 = {1,2,3,4,5};
Integer[] arr2 = {1,2,3,4,5};
boolean isSame = Arrays.deepEquals(arr1, arr2);
System.out.println(isSame);


/*
equals
1) primitive type 비교까지 함
2) 동작은 deepEquals와 같음

-) deepEquals와 equals의 차이는 deepCopy와 thinCopy 차이와 비슷
*/
isSame = Arrays.equals(arr1, arr2);
System.out.println(isSame);


/*
fill
1) 특정값으로 배열 초기화할 때
2) fill 이외에도 초기화해주지않으면 알아서 기본값으로 채움
*/
int[] numArr2 = new int[10];
Arrays.fill(numArr2, 10);
for(int i : numArr2){
System.out.println(i);
}


/* sort
1) 배열 요소를 오름차순으로 정렬, 내부적으로 루프중첩시켜서 돌리는데.....;;
- 정렬 최적화 알고리즘을 익힙시다

2) 레퍼런스 타입 정렬 기준 필드, 정렬 기준(오름, 내림차순)
- java.util.Comparator, java.util.Comparable

3) 새로운 배열 리턴하지않고 파라미터 배열을 변경함 : 리턴타입 void임
*/
int[] numArr3 = {6,3,1,4,3,2,1};
Arrays.sort(numArr3);
for(int i : numArr3){
System.out.println(i);
}

Student s1 = new Student(1);
Student s2 = new Student(2);
Student s3 = new Student(6);
Student s4 = new Student(5);
Student s5 = new Student(3);
Student s6 = new Student(7);
Student[] students = {s1, s2, s3, s4, s5, s6};

Arrays.sort(students);

StringBuffer result = new StringBuffer().append("번호순(오름차순) : ");
for (Student s : students){
result.append(s.getNum() + " ");
}
System.out.println(result);


/*
binarySearch
1) 메서드명 그대로 바이너리써치를 함, 반으로 나눠서 타겟 찾기 : 2개로 분할(Binary)
2) 써치하기 전에 쏘팅해둬야함
- 중간을 잘라서 초과, 미만을 가지고 완전탐색보다 더 적게 탐색함
- 레퍼런스의 경우 소팅할 때 특정 필드를 기준으로 소팅
*/
int res = Arrays.binarySearch(students, s3); // 소팅하고나서 몇번째에 속할까?
System.out.println(res+1 + "번째에 있습니다"); // index+1



// toString : 배열 요소 출력, toString을 보기 좋은 형태로 오버라이딩해서 씀
System.out.println(Arrays.toString(numArr3));


}
}

/* java.util.Comparable : binarySearch0에서 Comparable */
class Student implements Comparable<Student> {
private int num;

public Student(int num){
this.num = num;
}

public int getNum() {
return num;
}

@Override
public int compareTo(Student compare) {
/* 0번째 인덱스부터 : 0과 1비교(파라미터 Student가 뒷 순서)

[정렬 기준]
1) 오름차순 : 앞 인덱스가 뒷 인덱스보다 작을 때 -1
2) 내림차순 : 앞 인덱스가 뒷 인덱스보다 작을 때 1
*/
if(num < compare.getNum()){
return -1;
} else if(num == compare.getNum()){
return 0;
}
return 1;
}
}


/* java.util.Comparator interface implements */
class ArrCompare implements Comparator<Student> {

/* 오름차순 : o1 자리가 더 앞선 자리고, 작을 때 -1 리턴하면(인덱스와 리턴하는 값의 관계) */
@Override
public int compare(Student o1, Student o2) {
if(o1.getNum() < o2.getNum()){
return -1;
} else if(o1.getNum() == o2.getNum()){
return 0;
}

return 1;
}
}


2) java.lang Wrapper 클래스들

- primitive type 데이터를 내부 데이터로 갖는 포장 클래스

- 내부 데이터는 변경할 없고, 변경효과를 가지려면 새로운 Wrapper 인스턴스 생성해야함

- 박싱과 언박싱

(1) 박싱 : 내부데이터를 포장하는

(2) 언박싱 : 포장된 내부데이터를 꺼내는


- 사용할까?

(1) primitive type reference type으로 변경 -> 자료형에 맞는 메서드를 가짐 : 유틸리티 역할

public class WrapperTest {

/*
1) Byte
2) Short
3) Character
4) Integer
5) Float
6) Long
7) Double
*/

public static void main(String[] args) {
/* 박싱하기 */
Integer num = new Integer(10);
Integer num2 = Integer.valueOf(10); // static, return type Integer
Integer num3 = 20; //자동 박싱, java5~


/* 언박싱
1) 내부 데이터를 다른 타입으로 꺼낼 수 있음 : 내부적으로 캐스트 연산자 사용
2) 자동 언박싱도 됨 : 3번째 줄, java5~
*/
double data = num.doubleValue();
System.out.println(data);
int data2 = num;


/* parseInt : primitive 타입(int)으로 변경 */
try{
System.out.println(Integer.parseInt("1"));
} catch(NumberFormatException e){
System.out.println(e.getMessage());
}


/* 주의할 점
1)내부 데이터를 비교할 때 ==, != 연산자를 그냥 사용해서는 안됨
- 좁은 범위 내에서는 비교가 가능하지만 어떤 값이 저장될지 모르는 상태일 때는 equals 사용
=> Object.equals를 오버라이딩함 : primitive type 변환하고 값만 비교
*/
Integer compare1 = new Integer(1);
Integer compare2 = new Integer(1);

System.out.println(compare1 == compare2); // false
System.out.println(compare1.equals(compare2)); // true
}
}



3) java.lang.Math, java.util.Random

- Math

(1) 수학 유틸리티

(2) 모두 static 메서드

(3) 메서드를 직접 구현해보는 좋음 : 반올림 메서드가 첫번째 자리에서 반올림하는데 3번째 자리에서 반올림되게 커스텀해본다던지...


- Random

(1) 다양한 타입의 랜덤값을 얻기위한 메서드를 가진 유틸 클래스 : Math.random() 내부적으로 Random double 랜덤 메서드를 사용함

(2) 랜덤 인스턴스 생성할 시드값을 정해줄 있는데 시드값이 같을 경우 같은 난수들이 리턴됨

import java.util.Random;

public class MathRandomTest {
public static void main(String[] args) {
// random : 0.0 <= < 1.0 랜덤 double 리턴, 커스텀해서 사용
double random = Math.random();
System.out.println(random);

// 랜덤주사위 눈
int num = (int)(Math.random() * 6) + 1;
System.out.println(num);


// Random : 같은 시드값인 경우 같은 난수 생성
Random random1 = new Random(1234);
Random random2 = new Random(1234);

int[] arr1 = new int[6];
int[] arr2 = new int[6];

for(int i=0; i<arr1.length; i++){
arr1[i] = random1.nextInt(10); //bound 지정없으면 32비트 정수 표현범위 다 포함
arr2[i] = random2.nextInt(10); //bound 지정하면 0<= < n (int만)
}

for(int i=0; i<arr1.length; i++){
System.out.println(arr1[i] + ", " + arr2[i]);
}


}
}



[API]

- 아 프로그래밍할 때 도움주는 API 이런 것들이 있구나

- 객체지향은 이런거구나 디자인 참고하자