210705 월
<배열>
1. 배열
4) 배열 복사
(1) 얕은 복사
: 객체의 주소 값만 가져와 참조형 변수에 저장하고 하나의 객체를 두 변수가 참조하는 것
(2) 깊은 복사
: 새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사하는 것
package com.kh.array;
import java.util.Arrays;
public class B_ArrayCopy {
//얕은 복사 : 배열의 주소만을 복사
//깊은 복사 : 동일한 새로운 배열을 하나 생성해서 실제 내부 값들을 복사
public void method1() {
int[] origin = {1, 2, 3, 4, 5};
// origin 배열을 copy로 복사
int[] copy = origin;
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
//복사 된 copy 배열의 2번 인덱스 값 변경
copy[2] = 99; //=> 이것이 바로 변경 처리
System.out.println("=====복사본 배열 값 변경 후 =====");
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
/*답
* 원본 배열 출력
1 2 3 4 5
복사본 배열 출력
1 2 3 4 5
=====복사본 배열 값 변경 후 =====
원본 배열 출력
1 2 99 4 5
복사본 배열 출력
1 2 99 4 5
*/
//copy 인덱스 2번 값만 바꿨지만 원본과 복사본 값 모두 바뀌었다.
//copy만 변경해도 origin 배열 값도 변경 되어 있음을 확인
//그 이유는 origin과 copy가 같은 배열을 참조 하고 있기 때문(같은 주소값)
System.out.println();
System.out.println("origin의 주소값 : " + origin.hashCode());
System.out.println("copy의 주소값 : " + copy.hashCode());
//답
//origin의 주소값 : 705927765
//copy의 주소값 : 705927765
//해쉬 코드가 같다 = 같은 것을 참조한다
}
//복사 된 새로운 배열을 만들기 위해서는 깊은 복사 필요
public void method2() {
//1. for문
// 새로운 배열을 생성한 후 반복문을 통해 값을 대입
int[] origin = {1, 2, 3, 4, 5};
int[] copy = new int[5];
//현재 copy는 비어있다, 현재는 0
for(int i = 0 ; i < origin.length ; i++) {
//반복문을 통해 origin에 있는 값들을 copy에 대입
copy[i] = origin[i];
//copy1번에 origin1번.. 이런식으로 복사해준 격
}
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
/*원본 배열 출력
1 2 3 4 5
복사본 배열 출력
1 2 3 4 5 */
copy[2]=99;
System.out.println("====copy[2]변경 후=====");
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
/*====copy[2]변경 후=====
원본 배열 출력
1 2 3 4 5
복사본 배열 출력
1 2 99 4 5
깊은 복사 시 복사본 배열만 99로 변경 된 것 확인
*/
System.out.println();
System.out.println("origin의 주소값 : " + origin.hashCode());
System.out.println("copy의 주소값 : " + copy.hashCode());
/*
* origin의 주소값 : 705927765
copy의 주소값 : 366712642
주소 값도 다르다
*/
}
public void method3() {
//2. System 클래스의 arraycopy 메소드를 이용한 복사
int[] origin = {1, 2, 3, 4, 5};
int[] copy = new int[10];
/* System.arraycopy(원본배열(src), 복사 시작 인덱스(srcPos) => 어디서부터 할거냐
, 복사본 배열(dest), 복사본 배열에서 복사가 시작될 위치(destPos),
복사하고자 하는 길이(length ); */
System.arraycopy(origin, 0, copy, 2, origin.length);
//origin의 0부터 복사해서 copy의 2번에 가져다가 붙여 넣어라
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
/*답
* 원본 배열 출력
1 2 3 4 5
복사본 배열 출력
0 0 1 2 3 4 5 0 0 0
*/
// 다른 주소 값을 가지므로 한 배열의 값 변경 시 다른 배열 영향 받지 않음(깊은 복사)
}
System.out.println();
System.out.println("origin의 길이 : " + origin.length);
System.out.println("copy의 길이 : " + copy.length);
System.out.println("origin의 주소값 : " + origin.hashCode());
System.out.println("copy의 주소값 : " + copy.hashCode());
/*답
* origin의 길이 : 5
copy의 길이 : 10
origin의 주소값 : 705927765
copy의 주소값 : 366712642
*/
//다른 주소 값을 가지므로 한 배열의 값 변경시 다른 배열 영향 받지 않음(깊은 복사)
//System.arraycopy 메소드를 통해 복사 위치, 복사 개수 등 지정 가능
//물론 for문의 인덱스를 조절하여 같은 기능 구현 가능함
}
public void method4() {
//3. Arrays 클래스에서 제공하는 copyOf 메소드 사용
//Arrays 클래스는 배열을 이용할 때 유용한 메소드를 모아놓은 클래스
int[] origin = {1, 2, 3, 4, 5};
//복사본 배열 = Arrays.copyOf(원본 배열, 복사할 길이);
int[] copy = Arrays.copyOf(origin, 3);
//복사할 길이에 입력한 크기만큼 새로운 배열이 할당 되고
//원본 배열의 첫 번째 인덱스부터 가능한 길이만큼 복사해옴
//java api 8 (해당 메소드 shift + f2)
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
/*
* 원본 배열 출력
1 2 3 4 5
복사본 배열 출력
1 2 3 4 5
=> copy의 숫자를 5에서 10으로 변경했을 때
복사본 배열 출력
1 2 3 4 5 0 0 0 0 0
=> copy의 숫자를 10에서 3으로 변경했을 때
복사본 배열 출력
1 2 3
*/
}
}
public void method5() {
//4. clone 메소드를 이용한 복사
// 시작 인덱스를 지정할 수 없으며 원본 배열 통채로 복사해 새로운 배열 할당
int[] origin = {1, 2, 3, 4, 5};
int[] copy = origin.clone();
System.out.println("원본 배열 출력");
for(int i = 0 ; i < origin.length ; i++) {
System.out.print(origin[i] + " ");
}
System.out.println();
System.out.println("복사본 배열 출력");
for(int i = 0 ; i < copy.length; i++) {
System.out.print(copy[i] + " ");
/*원본 배열 출력
1 2 3 4 5
복사본 배열 출력
1 2 3 4 5*/
}
System.out.println("origin의 주소값 : " + origin.hashCode());
System.out.println("copy의 주소값 : " + copy.hashCode());
/*
* 1 2 3 4 5 origin의 주소값 : 705927765
copy의 주소값 : 366712642
*/
//얕은 복사와는 다르다. 새로운 공간 출력.
}
}
package com.kh.array;
import java.util.Arrays;
public class C_ArraySort {
//배열 정렬
public void method1() {
//배열을 정렬하기에 앞에서 변수를 가지고 값을 변경해보자
//우선 두 개의 변수의 값을 서로 변경하는 방법
int num1 = 20;
int num2 = 10;
System.out.println("===변경 전===");
System.out.println("num1 : " + num1);
System.out.println("num2 : " + num2);
// num1과 num2의 값을 서로 바꾼다고 생각해보자.
//num1 = num2;
//num2 = num1;
//=> 이렇게 하면 num2 값이 num1으로 가고 num1값이 다시 num2로 가기 때문에 ㅇ나됨
//따라서 값을 임시로 보관할 새로운 변수를 만들어 값을 이동 시켜야 함
//System.out.println("===변경 후===");
//System.out.println("num1 : " + num1);
//System.out.println("num2 : " + num2);
/*===변경 전===
num1 : 20
num2 : 10
===변경 후===
num1 : 10
num2 : 10*/
int temp;
temp = num1;
num1 = num2;
num2 = temp;
System.out.println("===변경 후===");
System.out.println("num1 : " + num1);
System.out.println("num2 : " + num2);
/*===변경 후===
num1 : 10
num2 : 20*/
}
public void method2() {
//배열도 동일하게 위치 변경 가능
int[] arr = {2, 1, 3}; // 하나씩 왼쪽으로 밀고 싶다 => 똑같이 임시 변수를 만들자
int temp = arr[0];
arr[0] = arr[1];
arr[1] = arr[2];
arr[2] = temp;
for(int i = 0 ; i < arr.length ; i++) {
System.out.println("arr[" + i + "] : " + arr[i]);
}
/* 답
* arr[0] : 1
arr[1] : 3
arr[2] : 2
*/
}
public void method3() {
//삽입 정령(insertion sort)
//배열의 n번 인덱스 값을 0번 ~ n-1 번 인덱스까지 비교
//비교 주체 비교 대상
// i = 1일 때 j = 0 ~ 0
// i = 2일 때 j = 0 ~ 1
// i = 3일 때 j = 0 ~ 2
// i = 4일 때 j = 0 ~ 3
// i = 1부터 마지막까지 반복할 때 => 외부 for문
// j = 0부터 i-1까지 반복 => 내부 for문
int[] arr = {2, 5, 4, 1, 3};
for(int i = 1 ; i < arr.length ; i++){
//인덱스가 증가할 때마다 처음부터 해당 인덱스 전까지 값을 비교하는 반복문
for(int j = 0 ; j < i ; j++) {
System.out.println("현재 인덱스 위치 : " + i + ", " + j);
if(arr[i] < arr[j]) { //부호 반대로 할 경우 내림차순
System.out.println("====교환 발생====");
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
System.out.println(i + "회전 : " + Arrays.toString(arr));
}
}
System.out.println("================");
System.out.println("최종 결과 : " + Arrays.toString(arr));
/* 현재 인덱스 위치 : 1, 0
1회전 : [2, 5, 4, 1, 3]
현재 인덱스 위치 : 2, 0
2회전 : [2, 5, 4, 1, 3]
현재 인덱스 위치 : 2, 1
====교환 발생====
2회전 : [2, 4, 5, 1, 3]
현재 인덱스 위치 : 3, 0
====교환 발생====
3회전 : [1, 4, 5, 2, 3]
현재 인덱스 위치 : 3, 1
====교환 발생====
3회전 : [1, 2, 5, 4, 3]
현재 인덱스 위치 : 3, 2
====교환 발생====
3회전 : [1, 2, 4, 5, 3]
현재 인덱스 위치 : 4, 0
4회전 : [1, 2, 4, 5, 3]
현재 인덱스 위치 : 4, 1
4회전 : [1, 2, 4, 5, 3]
현재 인덱스 위치 : 4, 2
====교환 발생====
4회전 : [1, 2, 3, 5, 4]
현재 인덱스 위치 : 4, 3
====교환 발생====
4회전 : [1, 2, 3, 4, 5]
================
최종 결과 : [1, 2, 3, 4, 5]*/
}
public void method4() {
int[] arr = {2, 5, 4, 1, 3};
Arrays.sort(arr); //이것을 이용하면 바로 오름차순 정렬이 된다.
//Arrays.sort(arr, 0, 3);//fromIndex, toIndex
//0번 인덱스부터 3번 인덱스 저까지 정렬 : 0 ~ 2 정렬, 즉 부분 정렬
//하나의 이름을 가진 메소드가 매개 변수 타입(int, double, char...)과 개수에 따라 다르게 동작
//내림차순 정렬은 Comparator 객체 전달이 필요하다. => 나중에 학습할 예정
System.out.println(Arrays.toString(arr));
int[] copy = new int[arr.length];
for(int i = 0 ; i < copy.length ; i++) {
copy[i] = arr[copy.length - 1 - i];
//arr는 인덱스가 4, 3, 2, 1, 0 값으로 들어가게
//copy는 0, 1, 2, 3, 4로 올라가게 해준 것.
//오름차순을 내림차순으로 바꾼 것 뿐 어렵지않죠
}
//답
//[1, 2, 3, 4, 5]
//내림차순 결과
System.out.println(Arrays.toString(copy));
//답
//[5, 4, 3, 2, 1]
}
public void method5() {
int[] arr = {2, 5, 4, 1, 3};
for(int i = 1 ; i < arr.length ; i++){
//인덱스가 증가할 때마다 처음부터 해당 인덱스 전까지 값을 비교하는 반복문
for(int j = 0 ; j < i ; j++) {
if(arr[i] < arr[j]) { //부호 반대로 할 경우 내림차순
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
System.out.println("최종 결과 : " + Arrays.toString(arr));
}
}
}
}
}
package com.kh.array;
import java.util.Arrays;
import java.util.Scanner;
public class D_Overlap {
public void method1() {
//사용자에게 5개의 값을 입력 받아 배열에 저장
//단, 중복 값은 허용하지 않음
int[] arr= new int[5];
Scanner sc = new Scanner(System.in);
for(int i = 0; i < arr.length ; i++) {
System.out.print(i + "번째 정수 값 : ");
arr[i] = sc.nextInt();
//중복 여부 검사 반복문
for(int j = 0 ; j < i ; j++) {
if(arr[i] == arr[j]) { //중복 값이 존재할 경우
System.out.println("중복 값이 존재합니다. 다시 입력해주세요");
i--; //외부 for문의 i++과 상쇄
=> 중복이 발생했던 인덱스를 다시 입력 받게 함
break;
// 중복이 발생한 시점에서 더 이상 체크할 필요가 없으므로
//중복 검사 반복문 탈출
}
}
}
System.out.println(Arrays.toString(arr));
}
public void method2() {
//1~10 사이의 난수를 중복 없이 발생시켜 배열에 담기
int[] arr = new int[5];
for(int i = 0 ; i < arr.length ; i++) {
arr[i] = (int)(Math.random() * 10 + 1);
//중복 체크 반복문 만들기
for(int j = 0 ; j < i ; j++) {
if(arr[i] == arr[j]) {
System.out.println(j + "번째와 " + i + "번째 : " + arr[i] + "중복");
i--;
break;
}
}
}
System.out.println(Arrays.toString(arr));
//로또 번호 당첨기 만들 수 있다 ㅎㅎ
/*
* 0번째와 3번째 : 3중복
[3, 10, 7, 5, 1]
*/
}
}
package com.kh.arrayrun;
import com.kh.array.A_Array;
import com.kh.array.B_ArrayCopy;
import com.kh.array.C_ArraySort;
import com.kh.array.D_Overlap;
public class ArrayRun {
public static void main(String[] args) {
//A_Array a = new A_Array();
//a.method9();
//B_ArrayCopy b = new B_ArrayCopy();
//b.method4();
//C_ArraySort c = new C_ArraySort();
//c.method5();
D_Overlap d = new D_Overlap();
d.method2();
}
}
'웹개발 수업 > JAVA' 카테고리의 다른 글
[Day +12]객체 / 필드, 전역변수, 지역변수, 매개변수, 예약어(static, final), 생성자, 오버로딩 (0) | 2021.07.11 |
---|---|
[Day +11]객체 / 객체지향언어, 클래스, 캡슐화, 추상화, 접근 제한자, 필드 (0) | 2021.07.11 |
[Day +8] 배열1 (0) | 2021.07.11 |
[Day +7]분기문 (0) | 2021.07.11 |
[Day +6]반복문 (0) | 2021.07.11 |