재밌고 어려운 IT를 이해해보자~!
익명 객체(클래스), Comparator, sort 본문
조별 프로젝트를 하던 도중 풀리지않는 문제를 마주쳐서 포스팅을 하게 되었다...
문제의 발단
축구선수 클래스에는 가격, 파워, 이름을 멤버변수로 가지고있다.
우리는 축구선수 객체 리스트를 출력해줄때 가격순, 파워순, 이름순으로 출력해주는 기능을 도입하기로했다.
일단 배운 정렬중 선택정렬을 사용해서 가격순 정렬을 만들어 놓고 파워순,이름순 정렬도 비슷하니까 이건 모듈화를 해야겠다 라고 생각을 해서 모듈화를 진행하려고했다.
메서드의 메게변수로 리스트와 원하는Key값 (가격 or 파워 or 이름) 을 받아서
메게변수로 전달 받은 것을 기준으로 정렬을 시켜주는 메서드를 만들고 싶었다!
하지만...멤버변수는 private으로 보호되어있었고 접근하기위해선 getter, setter 메서드를 이용해야헀다.
음.. 보통 메게변수를 받는 메서드를 작성할떄
void add(int num1, int num2) {
int total = num1 + num2;
System.out.println(total);
}
받을 변수 타입과 변수명을 작성해주고 기능을 동작하는 방식으로 작성된다. 따라서 내가 만든 메서드에 적용하려면..?
public static void printByPrice() {
System.out.println("====가격별 출력====");
for (int a = 0; a < datas.size() - 1; a++) {
int minIdx = a;
for (int i = a + 1; i < datas.size(); i++) {
if (datas.get(i).getPrice() > datas.get(minIdx).getPrice()) {
minIdx = i;
}
}
int temp = datas.get(a).getPrice();
datas.get(a).setPrice(datas.get(minIdx).getPrice());
datas.get(minIdx).setPrice(temp);
}
for (FootballPlayer data : datas) {
System.out.println(data);
}
}
나는 ..메게변수로 FootballPlayer 타입의 객체리스트 ArrayList<FootballPlayer> datas 이녀석이랑 FootballPlayer 가 가지고있는 메서드중 1개가아닌 (getPrice, getPower, getName) 3개중에 어떤게 들어와도 내 메서드가 이해할 수 있는 메서드 종합 명칭? 이 필요한 거라는 결론에 도달했다. 뭔가 산으로 가는 것 같고 맞는지 모르곘지만 메서드를 통틀어서 메게변수로 넣어줄 키워드가 없는 것 같았다 ....
public static void printByPrice(ArrayList<FootballPlayer> datas, FootballPlayer.getmethod method)
이런식으로 말이다.
인터넷을 찾아보니 메서드를 메게변수로 받는 방법이 있긴했는데,
그것 또한 적용시키기 어려웠던 것 같았다.
머리가아파서 다른밥법을 찾던 도중 Comparator 객체를 메게변수로 받는 sort 메서드를 찾았다.
정확히 말하면 Comparator를 사용한 익명객체인 것 같다. 어떻게 이렇게하면 내가원하는 멤버변수에 접근해서 리스트내에서 비교를하고 정렬을 할 수 있는걸까 ? 나도 똑같이 하면 될 것 같아서 내부를 확인 해 보았다.
sort
그만알아보도록하자
Type Parameters:T - the class of the objects to be sorted
Parameters:
a - the array to be sorted
c - the comparator to determine the order of the array. A null value indicates that the elements' natural ordering should be used.
Throws:
ClassCastException - if the array contains elements that are not mutually comparable using the specified comparatorIllegalArgumentException - (optional) if the comparator is found to violate the Comparator contract
라고한다....
Comparator
Comparator는 인터페이스이며 int compare(T o1, T o2); 메서드를 오버라이딩해서 사용하도록 선언되어있다.
전체적인걸 알기위해 익명객체도 알아야한다..!!
익명객체(클래스)
익명객체(클래스)는 특정 구현 부분만 따로 사용한다거나, 부분적으로 기능을 일시적으로 바꿔야 할 경우가 생길 때에 사용할 수 있는 것이다.
이름이 정의되어 있지 않은 객체이다.
예시를보자.
public class Anonymous {
public static void main(String[] args) {
Rectangle a = new Rectangle();
ChildRectangle child = new ChildRectangle();
System.out.println(a.get()); // 20
System.out.println(child.get()); // 10 * 20 * 40
}
}
class ChildRectangle extends Rectangle {
int depth = 40;
@Override
int get() {
return width * height * depth;
}
}
class Rectangle {
int width = 10;
int height = 20;
int get() {
return height;
}
}
클래스는 Rectangle과 그것을 상속받은 ChildRectangle이 있으며 각각의 객체는 객체변수명 a, child로 선언되어있다.
public class Anonymous {
public static void main(String[] args) {
Rectangle a = new Rectangle();
Rectangle anonymous = new Rectangle() {
int depth = 40;
@Override
int get() {
return width * height * depth;
}
};
System.out.println(a.get()); // 20
System.out.println(anonymous.get()); // 10 * 20 * 40
}
}
class Rectangle {
int width = 10;
int height = 20;
int get() {
return height;
}
}
annoymous 라는 객체는 마치 Ractangle 클래스를 상속받은 것 처럼 구현이 되어있다. 하지만 어디에도 클래스이름이 정의되어 있지 않고 객체만 생성된 것이다. 즉 혼자서는 무엇도 할 수 없고 무조건 상속(extends, implement)을 받은것처럼 인식되어야 기능 구현을 해야하는 녀석이다.
특이점으로는 객체 생성 후에 멤버변수, 메서드가 정의되고 세미콜론 ";" 이 붙는다.
Ractacgle Noname = new Ractangle () {
};
흐으음.. 어떤 학생 정보를 담기 위한 객체 이런느낌이 아니라 어떠한 클래스가 가지고있는 멤버변수와 메서드를 잠깐 빌려다 쓰기 위한 객체인 것 같다.
다시 본론으로 돌아가면,
Comprator인터페이스를 활용해서 익명 객체를 만들어 compare 메서드를 빌려다가 오버라이딩
한 후에 그 객체 자체 (c)를 sort에게 메게변수로 넘겨주면 오버라이딩 된 compare를 확인해 그 비교 기준으로
같이 넘어온 객체리스트or배열 (a)를 정렬하겠다는 의미 라고한다.
if (c.compare(src[mid-1], src[mid]) <= 0)
=>우리가 넘겨준 익명객체 c의 compare 메서드의 리턴값이 0보다 작거나 같을때 뭔가 한다! 굿굿:D
결론적으로 나는 저 Sort기능을 만들 실력이 안될 뿐더러, sort를 사용하는 것외에 내가 가진 지식으로 원하는 모듈화를 할 수 있었는가? 에 대한 답을 찾지 못하는게 슬프다.
따라서 일단 잘 활용해 보기로 했다.
public static Comparator<FootballPlayer> byPrice = new Comparator<FootballPlayer>() {
@Override
public int compare(FootballPlayer p1, FootballPlayer p2) {
return p1.price - p2.price;
}
};
datas.sort(FootballPlayer.byPrice);
FootballPlayer타입의 Comparator 인터페이스를 상속받은 익명객체 byPrice 선언 후 compare 메서드를
오버라이딩 해서 두개의 객체 가격을 비교한 값을 return ! 그럼 sort가 return받은 값을 가지고 음수 , 0, 양수일때를 판단해서 정렬해준다 .
함수명 | 기능 | 유효성 |
inputUid() | ID 입력 (이메일) | 00 @ 00 . 00 형식 |
inputUpw() | PW 입력 | 전부입력가능 |
inputName() | 이름 입력 | 문자만 입력가능 |
inputNickName() | 닉네임 입력 | 특수문자 입력 불가능 |
inputBirhday() | 생년월일 입력 | 1900~2023년생까지 8자리 숫자만 입력 가능 |
inputPhoneNumber() | 전화번호 입력 | 앞자리 01 + 016789 입력가능 11자리 숫자만 입력 가능 |
inputAddress() | 주소 입력 | 전부입력가능 |
inputNum() | 번호 입력받기 및 범위 유효성 검사 숫자 입력 | 유효범위 지정가능 |
'개인공부' 카테고리의 다른 글
프로젝트 관련 궁금증 정리 (0) | 2024.02.22 |
---|---|
Parameter(파라미터) 와 Attribute(속성) 의 차이 (0) | 2024.01.27 |
JSTL practice (0) | 2024.01.26 |
sql 의문점 TEST (2) | 2023.12.31 |
BufferedReader, StringBuilder (0) | 2023.12.12 |