본문 바로가기

카테고리 없음

[Java] 배열

 

 

Part1 배열

 

 

1. 배열: 하나의 공간에 여러개의 값을 담을 수 있음
            단, 같은 자료형의 값들이어야 함 
       =   > 배열의 각 인덱스 자리에 실제 값이 담김, 인덱스는 0부터 시작 
       =  >배열의 장점: 반복문 사용 가능 

 

2. 배열의 선언 및 할당

  1) 배열 선언방법 

     - 자료형  배열식별자 [ ] ;    int   arr1[  ];
     - 자료형[  ] 배열식별자;        int[   ]  arr1 ;      ==> 이 방법을 주로 사용

   2) 배열 할당
      - 배열에 몇개의 값이 들어갈지 배열의 크기를 정해주는 과정
        지정(할당) 갯수만큼 값이 들어갈 공간 생성

 

int[] arr; 						// 배열의 선언 
arr = new int[5]; 				// 배열의 값 할당


int[] arr = new int[5]			//배열의 선언과 할당 동시진행
								// 인덱스 길이가 5인 int 배열 arr 생성

    * 배열은 참조형 변수임 ( new 객체에 대입하는 변수는 참조형임 / 메모리의 heap 영역에 저장) 

    * 기본형 => 실제 값을 담을 수 있음 (일반변수), 자동초기화 없음

    * 참조형: 주소 값을 담을 수 있음 (참조변수)   --->배열, String, 자동초기화 있음\

 

	
		int i;
		double d;
		int[] iArr = new int[5];
		double[] dArr = new double[5];
		
//		System.out.println(i);   ==========> 출력불가: 기본형은 자동초기화 없음 
//		System.out.println(d);
		
		System.out.println(iArr[0]); // 출력가능 : 
        // 참조형은 자동초기화되므로 배열의 각 인덱스는 자동초기값을 가지고 있음
		System.out.println(dArr[0]); // 출력가능

 

3. 배열의 인덱스

 1) 배열 인덱스에 값 저장하기

배열이름 [인덱스넘버] = 값; // 0부터 시작

int[] arr = new int[5];

arr[0] = 1;
arr[1] = 2;
....

 

4. 배열의 길이

배열이름.length

//int형 배열을 선언하고
//5칸을 할당하고
// 사용자로부터 정수 다섯개를 입력받아
// 반복문을 이용해 합계 출력하기

 

	public void method6() {


			int[] nums = new int[5];
		    int sum = 0;
			Scanner sc = new Scanner(System.in);
			for (int i=0; i<= nums.length-1 ; i++) {
			System.out.println("정수를 입력해주세요 :");
				nums[i] = sc.nextInt();
			System.out.println("nums라는 배열의"+i+"번째 인덱스에 들어가는 값 " +nums[i]);
		        	sum += nums[i];
			}
				System.out.println(sum);
	}

 

 

5. 배열의 최대값, 최소값 

	int[] nums = new int[5];
	Scanner sc = new Scanner(System.in);
	for (int i=0; i<= nums.length-1 ; i++) {
			System.out.println("정수를 입력해주세요 :");
			nums[i] = sc.nextInt();
			System.out.println("nums라는 배열의"+i+"번째 인덱스에 들어가는 값 " +nums[i]);
	}
    
// 최소값 구하기
// 정수를 담을 변수를 하나 선언하여, 첫 번째 인덱스 값을 대입
// 둘둘 비교하여 min보다 작을 값이 나올 경우, 해당 값을 min에 대입 
    int min = nums[0];
	for (int i =1; i <nums.length ; i++ ) {
		if (nums[i]<min) {
			min = nums[i];
		}
  	}
		System.out.println("최소값: "+ min);

// 최대값 구하기
// 정수를 담을 변수를 하나 선언하여, 첫 번째 인덱스 값을 대입
// 둘둘 비교하여 max보다 큰 값이 나올 경우, 해당 값을 max에 대입
	int max = nums[0];
	for (int i = 1; i<nums.length ; i++) {
		if (nums[i]> max) {
			max = nums[i];
		}
	}
		System.out.println("최대값: "+ max);

 

 

// 1. 배열 선언 + 할당
int[] iArr = new int[5];		// iArr은 메모리 stack영역, int[]는 heap영역에 저장 (참조형)
								// iArr에는 참조형 int[5]가 저장되어있는 주소값이 저장됨
	
System.out.println(iArr);			
System.out.println("배열의크기 : "+iArr.length);			
// 배열이름.length : 배열의 길이 (크기) = > 정수타입 반환
// "." 참조연산자.직접접근연산자 (주소에 직접 접근한다. heap영역에 저장된 주소로 이동)
	
double[] dArr = new double[5];
System.out.println(dArr);
System.out.println("배열의 크기: "+dArr.length);
		// 기본형 => 자동초기화 없음 , 참조형 ==>자동초기화 있음
		// 기본형: 실제 값을 담을 수 있음 (일반변수)
		// 참조형: 주소 값을 담을 수 있음 (참조변수)   --->배열, String
		
		int i;
		double d;
		int[] iArr = new int[5];
		double[] dArr = new double[5];
		
//		System.out.println(i);   ==========> 출력불가: 기본형은 자동초기화 없음 
//		System.out.println(d);
		
		System.out.println(iArr[0]); // 출력가능 : 참조형은 자동초기화되므로 배열의 각 인덱스는 자동초기값을 가지고 있음
		System.out.println(dArr[0]); // 출력가능

 

// 참조자료형에서는 == (동등비교) 시  주소값을 비교한다 
// 문자열(참조자료형) 비교시에는 .equals()를 사용해야 한다
	
	System.out.println("iArr의 해시코드 주소값 :"+iArr.hashCode());
	System.out.println("dArr의 해시코드 주소값 :"+dArr.hashCode());
		// 해시코드: 주소값을 10진수 형태로 나타낸것
		
	int[] iArr2 = new int[3];
	System.out.println("iArr2의 해시코드 주소값 :"+iArr2.hashCode());
	System.out.println(iArr2 == iArr ); //false, 주소값비교
		

		// 반복분
		// 0번 인덱스부터 마지막 인덱스까지 1씩 증가하면서 순차적으로 출력 가능
		// 마지막인덱스 == 배열의크기 -1

 


// 배열의 아쉬운점
// 1. 한 번 지정한 배열의 크기는 변경이 불가함 
//    ==> 배열 크기 변경을 원한다면? 배열을 재생성 해야함 

public void method6() {
String[] sArr = new String[3];

sArr[0] = "이";
sArr[1] = "승";
sArr[2] = "철";

for( int i=0 ; i <sArr.length ; i++) {
System.out.println(sArr[i]);
}

System.out.println("재대입 전 hashCode :" + sArr.hashCode());
sArr = new String[5];
System.out.println("재대입 후 hashCode :" + sArr.hashCode());

 

/ 연결이 끊어진 기존의 배열은?
// (재대입전 hashCode의 주소값은?/ 연결이 끊어진 heap의 주소값)
// (stack영역의 변수가 가르치고 있는 주소 -> reference count, 
// reference count가 0인 주소들은 일정시간이 지나면 gc (garbage collector)가 치워줌 , 자동 메모리 관리 
//
// 배열은 항상 고유한 주소값 이 부여됨. 주소값이 다르면 다른 배열이다
//  기존 배열에 할당만 다시하면? => 기존 reference count가 끊기고, 새로운 주소값과 연결됨 (새로운 곳을 참조)
// 기존 연결고리(reference count)를 끊고 싶다면? 변수에 null 대입 (null : 아무것도 존재하지 않음을 의미하는 예약어)
// sArr = null;
//

sArr = null;
// sArr[0] = "집중하세요";  
//
// System.out.println(sArr[0]);      ==> 런타임 에러: java.lang.NullPointerException
// ==> 변수가 참조하는 주소값이 없음
System.out.println(sArr ); //  ==> 컴파일 가능: sArr =null 대입되어 있자나!


// null 이란? 참조자료형에 활용되는 개념으로, 참조변수의 주소값이 없음을 의미 
// 참조자료형의 자동초기값임 (자동초기값이자 기본값)
// 참조자료형은 원래 객체를 생성한 후 사용해야함, but! String은 별도의 객체를 생성하지 않음
String str = new String();
System.out.println(str);  // 컴파일시 " " (공백) 출력, String은 다른 참조자료형과 다르게 기본값이 " " 임(null아님)
str = null;
System.out.println(str); // 컴파일시 "null"출력, String 도 null을 대입할 수 있음 (자동초기값은 아님)

}

 


public void method7() {
// 배열 선언 및 할당과 동시에 초기화(대입)까지 끝내는 방법
// 방법1
// int[] arr1 = new int[4];
// arr[0] = 1;
// arr[1] = 1;
// arr[2] = 1;
// arr[3] = 1;
// 방법2
// int[] arr1 = new int[] {1, 3, 5, 8};
// 방법3
// int[] arr2 = {1, 3, 5, 8};
}

//
// 배열 복사 
// 1. 얕은 복사:
// 2. 깊은 복사: 

int[] copy = origin;  // origin이 가리키는 새로운 객체를 생성하지 않았음
			System.out.println();
			System.out.println("복사본배열출력 ");
			for (int i=0; i< copy.length; i++) {
				
				System.out.print(copy[i]+" ");
			}
			
			origin[2] = 99;
			System.out.println("\n원본배열 재출력");
			for (int i=0; i< origin.length; i++) {
				System.out.print(origin[i]+" ");
			}
			
			System.out.println("\n복사본배열출력");
			for (int i=0; i< copy.length; i++) {
				
				System.out.print(copy[i]+" ");	 // origin과 copy는 같은 주소값의 객체를 가리키고 있으므로 배열의 값은 같다 						
			}									// 원본 배열을 수정하면 복사본 배열도 수정된다 
			
			System.out.println("\n원본 배열의 해시코드"+origin.hashCode());		// 원본의 해시코드와 복사본의 해시코드는 같음 
			System.out.println("원본 배열의 해시코드"+copy.hashCode());
			
		}

 

 

// 2. 깊은복사1
		
		public void method9() {
			int[] origin = {1, 2, 3, 4, 5};
			// 1단계: 기존과 동일한 크기의 새 배열 생성 및 할당
			int[] copy = new int[origin.length];
			// 2단계: 
				for (int i=0; i < origin.length ; i++) {
					 	copy[i] = origin[i];
					}
				System.out.print("원본배열출력\n");
				for (int i=0; i< origin.length ; i++) {
					System.out.print(origin[i]);
				}
				System.out.print("\n복사본배열출력\n");	
					for (int j=0; j< copy.length ; j++) {
						System.out.print(+copy[j]);
					}
				}
						
				// 실제 우리가 원하는 배열 내부 값들이 복사된 것을 확인 가능, 주소값 복사 아님
//2. 깊은복사 2
		public void method10() {
			// 새로운 배열을 생성한 후 
			// System 클래스의 arraycopy( 매서드 호출
			// 몇변 인덱스부터 몇개를, 어느 위치부터 넣을 것인지 직접 지정 가능 ( ) 안에 작성
			
			int[] origin = {1, 2, 3, 4, 5};
			int[] copy = new int[10];

 

 

 

[표현법]
//  System.arraycopy(원본배열이름, 원본배열에서 복사를 시작할 인덱스, 복사본 배열 이름, 복사본 배열에서 복사가 시작될 인덱스, 복사할 개수);
//	arraycopy는 10개까 복사가 기본값
			
			System.arraycopy(origin, 0, copy, 0, 5);
			System.arraycopy(origin, 0, copy, 3, 5);
//			System.arraycopy(origin, 2, copy, 9, 2); --=> arrayintdexoutofbounds에러 발생! index[10]값이 존재하지 않음 
			
			
			System.out.println(); 
			
			System.out.println("복사본배열출력 ");
			for (int i=0; i< copy.length; i++) {
				
				System.out.print(copy[i]+" ");
			}
			System.out.println("\n원본 배열의 해시코드"+origin.hashCode());		// 원본의 해시코드와 복사본의 해시코드는 같음 
			System.out.println("복사본 배열의 해시코드"+copy.hashCode());

			}

 

 

 

 

	
		// 깊은복사 3 . copyof() 사용
		public void method11() {
			int[] origin = { 1, 2, 3, 4, 5};
			
			//Arrays클래스에서 제공하는 copyOf()
			// 표현법 
//				복사본배열 = Arrays.copyOf(원본배열 이름, 복사할 개수)
			int[] copy = Arrays.copyOf(origin, 10);
			// 원본배열보다 큰 값을 제시하면 복사본배열에 공간이 생성됨 
			System.out.println("복사본 출력:");
			for ( int i=0; i < copy.length; i++) {
				System.out.print(copy[i]+ " ");
				
			}
//			
//			System.arraycopy(): 몇번 인덱스를 몇개부터, 어느 인덱스에 복사할 것인지 지정가능
//			Arrays.copyOf(): 무조건 원본배열의 0번 인덱스부터 복사 진행 (지정개수만큼
//
		// 깊은복사 4. clone()
		public void method12() {
//			복사본 배열 이름 = 원본배열이름.clone();
			int[] origin = {1, 2, 3, 4, 5};
			int[] copy = origin.clone();
			
			//원본배열과 완전히 똑같이 복사 
			
			System.out.println("복사본 출력:");
			for ( int i=0; i < copy.length; i++) {
				System.out.print(copy[i]+ " ");
			}
			System.out.println();
			// Arrays.toString (배열출력)
			System.out.println(Arrays.toString(copy));
				
		}
		
}