① 문제
▶기존의 객체배열을 복사 → 새로운 객체배열을 생성, 정렬(오름/내림차순) → 객체배열 주소값 반환
② 못 풀었던 원인
▶ 1) 객체배열을 복사하기 위해서, 새로운 객체배열의 크기를 지정해서 생성을 해줘야하는데 나중에 알았음
▶ 2) 새로운 객체배열 생성에서 new를 통해 클래스기본생성자를 사용 못함
▶ 3) 지역변수는 초기화를 꼭 해줘야 하는데 잊어버림
1. 객체배열 복사( System.arraycopy( ) )
1) 클래스 총 4개
- MemberController (컨트롤러) : 기능 수행
- MemberMenu (뷰) : 사용자 화면출력 부분
- Member (모델 역할) : 데이터 저장
- Run (실행파일)
2) 객체배열 데이터 바꾸지 않고 정렬하기
기존의 회원 객체배열(mem)을 변경하지 않고, 기존 배열 복사하기
public class MemberController {
//필드
public static final int SIZE = 10;
private int memberCount =0; //현재 회원수 필드
private Member[] mem = new Member[SIZE]; //회원들의 정보를 담는 객체 배열
public Member[] sortIdAsc() {
// 기존의 회원 객체 배열(mem)을 변경하지 않고 단지 정렬된 결과만을 보여주기 위해
// 기존의 배열 복사해서 사용 (clone(), System.arraycopy() 둘 중 하나 사용해서 복사)
}
2. 삽질 (오류...)
시도1) copy를 new연산자를 통해 생성하지 않아서 안됨!!
public Member[] sortIdAsc() {
// 기존의 회원 객체 배열(mem)을 변경하지 않고 단지 정렬된 결과만을 보여주기 위해
// 기존의 배열 복사해서 사용 (clone(), System.arraycopy() 둘 중 하나 사용해서 복사)
copy = System.arraycopy(mem, 0, copy, 0, mem.length); ==> 안됨
}
시도2) mem의 길이(SIZE = 10) > 실제 값이 채워진 길이 => null에서 copy[k].getUserId()처럼 값을 가져오려하면 오류!
mem.length --> 10 ( =SIZE )
만약 입력된 member --> 6개 이면 (memberCount = 6)
mem에서 입력된 칸은 6개이고 4개는 null이라면
mem을 복사한 copy도 --> 값이 입력된 칸은 6개이고 4개는 null
i= 0~5일때 copy[ i ].getUserId( ) --> 오류X (값 있으니까)
i= 6~9일때 copy[ i ].getUserId( ) --> 오류O (값 없는 null에서 getter메서드를 쓰려고 하기 때문)
//필드부
private int memberCount =0; //현재 회원수 필드 (추가시 ++)
private Member[] mem = new Member[SIZE];
//메소드부
public Member[] sortIdAsc() {
// 기존의 회원 객체 배열(mem)을 변경하지 않고 단지 정렬된 결과만을 보여주기 위해
// 기존의 배열 복사해서 사용 (clone(), System.arraycopy() 둘 중 하나 사용해서 복사)
Member[] copy = new Member[mem.length]; //mem.lenght --> 10 (=SIZE)
copy = System.arraycopy(mem, 0, copy, 0, mem.length); //mem의 길이는 10이지만
//실제로 값이 있는 크기가 10보다 작은 경우 오류
for(int i=0; i<copy.length; i++) { //copy.lenght --> 10
for(int k=0; k<i; k++) {
String bef= copy[k].getUserId();
String aft = copy[i].getUserId();
if(aft.compareTo(bef)<0) {
copy[i].setUserId(bef);
copy[k].setUserId(aft);
}
}
}
return copy;
}
시도3) 지역변수 copy는 무조건 초기화를 해줘야 한다!
public Member[] sortIdAsc() {
// 기존의 회원 객체 배열(mem)을 변경하지 않고 단지 정렬된 결과만을 보여주기 위해
// 기존의 배열 복사해서 사용 (clone(), System.arraycopy() 둘 중 하나 사용해서 복사)
Member[] copy;
for(int i=0; i<mem.length; i++) {
System.arraycopy(mem, 0, copy, 0, mem.length );
}
3. 해결!
public Member[] sortIdAsc() {
// 기존의 회원 객체 배열(mem)을 변경하지 않고 단지 정렬된 결과만을 보여주기 위해
// 기존의 배열 복사해서 사용 (clone(), System.arraycopy() 둘 중 하나 사용해서 복사)
Member[] copy = new Member[memberCount];
System.arraycopy(mem, 0, copy, 0, memberCount);
// copy 배열을 아이디 별 오름차순 정렬 진행
// --> HINT : String 클래스의 compareTo() 메소드 활용
// copy 주소 값 리턴
for(int i=0; i<copy.length; i++) {
for(int k=0; k<i; k++) {
String bef= copy[k].getUserId();
String aft = copy[i].getUserId();
if(aft.compareTo(bef)<0) {
copy[i].setUserId(bef);
copy[k].setUserId(aft);
}
}
}
return copy;
}
Member[ ] copy = new Member[ memberCount ];
System.arraycopy( mem, 0, copy, 0, memberCount );
1) 객체배열 copy : Member 클래스의 생성자를 통한 생성 및 초기화
2) 객체 배열 길이 : memberCount --> null포인터 오류 방지
출처 및 참고 : kh정보교육원 실습문제
'Java > Java 문제' 카테고리의 다른 글
[코테] level1 - 문자열 (0) | 2021.06.23 |
---|---|
[Java] 조건문(if, switch)_실습문제 (0) | 2021.05.08 |
[Java] 배열_실습문제(easy & hard) (0) | 2021.05.05 |