본문 바로가기
Java/Java 문제

[Java] 객체배열 & mvc 문제 정리1_(객체배열 복사_System.arraycopy( ))

by 콧등치기국수 2021. 5. 18.

① 문제

▶기존의 객체배열을 복사 → 새로운 객체배열을 생성, 정렬(오름/내림차순) → 객체배열 주소값 반환

② 못 풀었던 원인

▶ 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