객체의 주소 값만 가져와 참조형 변수에 저장하고 하나의 객체를 두 변수가 참조하는 것

class ArrayExample2
package edu.kh.array.ex;
import java.util.Arrays;
public class ArrayExample2 {
// 얕은 복사 (shallow : 얕은)
// -> 주소를 복사하여 서로 다른 두 변수가
// 하나의 배열(또는 객체)을 참조하는 상태를 만드는 복사 방법
public void shallowCopy() {
int[] arr = {1, 2, 3, 4, 5};
// 얕은 복사 진행
int[] copyArr = arr; // 주소만 복사
System.out.println("주소 확인");
System.out.println("arr : " + arr);
System.out.println("copyArr : " + copyArr);
// 배열 값 변경
System.out.println("변경 전");
System.out.println("arr : " + Arrays.toString(arr));
System.out.println("copyArr : " + Arrays.toString(copyArr));
// 얕은 복사한 배열의 값을 변경
copyArr[2] = 1000;
System.out.println("변경 후");
System.out.println("arr : " + Arrays.toString(arr));
System.out.println("copyArr : " + Arrays.toString(copyArr));
}
}

새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사하는 것

1) for(inti= 0; i< arr1.length; i++) {
arr2[i] = arr1[i];
}
가장 대표적인 방법
2) System.arraycopy(arr1, 0, arr2, 0, arr1.length);
3) arr2= Arrays.copyOf(arr1, arr1.length);
이클립스에서 제공하는 조금 편한 복사
4) arr2= arr1.clone() ;
위험하다, 최대한 자세하게 쓰지 않은 경우 사용하는 것을 추천하지 않음
class ArrayExample2
public void deepCopy() {
int[] arr = {1,2,3,4,5}; // 원본
// 1. for문을 이용한 깊은 복사
int[] copyArr1 = new int[arr.length]; // 5칸 짜리 배열 생성
for(int i=0; i<arr.length; i++) {
copyArr1[i] = arr[i];
}
// 2. System.arraycopy(원본배열, 원본 복사 시작 인덱스,
// 복사배열, 복사배열의 삽입 시작 인덱스, 복사길이);
int[] copyArr2 = new int[arr.length];
System.arraycopy(arr, 0, copyArr2, 0, arr.length);
// 3. 복사할 배열 참조 변수 = Arrays.copyof(원본 배열, 복사할 길이);
int[] copyArr3 = Arrays.copyOf(arr, arr.length);
// 값 변경 후 확인
copyArr1[2]=0;
copyArr2[2] = 500;
copyArr3[2] = 1000;
System.out.println("arr : " + Arrays.toString(arr));
System.out.println("copyArr1 : " + Arrays.toString(copyArr1));
System.out.println("copyArr2 : " + Arrays.toString(copyArr2));
System.out.println("copyArr3 : " + Arrays.toString(copyArr3));
}

class ArrayExample2
로또 번호 생성기
// 배열을 이용한 중복 데이터 제거 + 정렬
public void createLottoNumber() {
// 로또 번호 생성기
// 1. 1 ~ 45 사이 중복되지 않은 난수 6개 생성
// 2. 생성된 난수가 오름차순으로 정렬
// 1) 정수 6개를 저장할 배열 선언 및 할당
int[] lotto = new int[6];
// 2) 생성된 배열을 처음부터 끝까지 순차 접근하는 for문 작성
for(int i=0; i<lotto.length; i++) {
// 3) 1 ~ 45 사이의 난수 생성
int random = (int)(Math.random() * 45 + 1);
// 0.0 <= x < 1.0
// 0.0 <= x * 45 < 45.0
// 1.0 <= x * 45 + 1 < 46.0
// i <= (int)(x * 45 + 1) < 46
// 4) 생성된 난수를 순서대로 배열 요소에 대입
lotto[i] = random;
// System.out.println(lotto[i] + " ");
// 5) 중복 검사를 위한 for문 작성
for(int j=0; j<i; j++) {
// 6) 현재 생성된 난수와 같은 수가
// 앞쪽 요소에 있는지 검사
if(random == lotto[j]) {
i--;
// i가 1씩 증가할 때 마다 난수가 하나 생성
// -> 중복 값이 있으므로 난수를 새로 하나 더 생성 해야함
// --> i는 0~5까지 6회 반복 되지만
// i값을 인위적으로 1 감소시켜 7회 반복되는 모양을 만듦
break;
// 앞쪽에서 중복 데이터를 발견하면
// 남은 값을 비교할 필요 없음
// -> 효율 향상을 위해서 검사하는 for문 종료
}
}
} // 바깥쪽 for문 끝
// 7) 오름차순 정렬
// -> 선택, 삽입, 버블, 퀵 등등
// --> 자바가 정렬 방법을 미리 만들어서 제공하고 있음
// Arrays.sort(배열명) : 배열 내 값들이 오름차순으로 정렬됨
Arrays.sort(lotto);
// 내림차순 정렬
// Collections.reverseOrder()
// Arrays.sort(lotto, Collections.reverseOrder());
// 결과 출력
System.out.println(Arrays.toString(lotto));
}


class ArrayPractice
public void practice8() {
Scanner sc = new Scanner(System.in);
while(true) { // 3 이상의 홀수가 입력 될 때 까지 무한 반복
// -> 3 이상 홀수가 입력되면 break문으로 종료
System.out.print("정수 : ");
int input = sc.nextInt();
if(input %2==0 || input<3){ // 짝수 또는 3 미만인 경우 -> 반복
System.out.println("다시 입력하세요.");
}
else {
// 입력 받은 정수 만큼의 크기를 가지는 배열 생성
int[] arr = new int[input];
int num = 0; // arr 배열에 대입될 값
for(int i=0; i<arr.length; i++) {
if(i<=arr.length/2) { // 중간 이전 까지 -> 증가
arr[i] = ++num;
} else { // 중간 이후 -> 감소
arr[i] = --num;
} // 출력 시, 추가 (단, 마지막 제외)
if(i==arr.length-1) { // 마지막 바퀴
System.out.print(arr[i]);
}
else {
System.out.print(arr[i]+ " , ");
}
}
break; // while 반복 멈춤
}
}


class ArrayPractice
public void practice9() {
Scanner sc = new Scanner(System.in);
int[] input = new int[10]; // 10개의 값을 저장할 수 있는 정수형 배열 선언 및 할당
System.out.print("발생한 난수 : ");
for (int i=0; i<input.length; i++) { // 1~10 사이의 난수를 발생시켜 배열에 초기화한 후 출력하세요
int random = (int)(Math.random() * 10 + 1);
System.out.print(random + " ");
}
}


class ArrayPractice
public void practice10() {
int[] arr= new int[10];
System.out.print("발생한 난수 : ");
for(int i=0; i<arr.length; i++) {
arr[i] = (int)(Math.random() * 10 + 1);
System.out.print(arr[i] + " ");
}
int min = arr[0];
int max = arr[0];
for(int i=0; i<arr.length; i++) {
if(max < arr[i]) {
max = arr[i];
} else if(arr[i] < min) {
min = arr[i];
}
}
System.out.println();
System.out.println("최대값 : " + max);
System.out.println("최소값 : " + min);
}


class ArrayPractice
public void practice11() {
int[] arr = new int[10]; // 10개의 값을 저장할 수 있는 정수형 배열을 선언 및 할당
System.out.print("발생한 난수 : ");
for (int i=0; i<arr.length; i++) {
// 난수 생성 -> 대입(단, 중복 제거)
arr[i] = (int)(Math.random() * 10 + 1); // 1 ~ 10사이 난수
// 중복 확인 시 i값을 감소 시켜
// 다음 반복에서 현재 인덱스에 난수 덮어쓰기
for(int j=0; j<i; j++) {
if(arr[i] == arr[j]) { // 현재 생성된 난수가 앞서 대입된 난수와 같은 경우 == 중복
i--; // i를 i 감소 시킴
// 바깥쪽 for문 반복 시 i가 다시 1 증가
// -1 + 1 == 0 (제자리)
break;
}
}
}
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i] + " ");
}
}


class ArrayPractice
public void practice12() {
// 1) 정수 6개를 저장할 배열 선언 및 할당
int[] lotto = new int[6];
// 2) 생성된 배열을 처음부터 끝까지 순차 접근하는 for문 작성
for(int i=0; i<lotto.length; i++) {
// 3) 1 ~ 45 사이의 난수 생성
int random = (int)(Math.random() * 45 + 1);
// 4) 생성된 난수를 순서대로 배열 요소에 대입
lotto[i] = random;
// 5) 중복 검사를 위한 for문 작성
for(int j=0; j<i; j++) {
// 6) 현재 생성된 난수와 같은 수가
// 앞쪽 요소에 있는지 검사
if(random==lotto[j]) {
i--;
break;
}
}
}
Arrays.sort(lotto);
System.out.println(Arrays.toString(lotto));
}


class ArrayPractice
public void practice13() {
Scanner sc = new Scanner(System.in);
System.out.print("문자열 : "); // 문자열을 입력 받아
String input = sc.nextLine();
// 문자열에 어떤 문자가 들어갔는지 배열에 저장
char[] str = new char[input.length()];
int count = 0; // 카운트용 변수
System.out.print("문자열에 있는 문자 : ");
for(int i=0; i<str.length; i++) {
str[i]=input.charAt(i); // 문자열에 있는 문자 : a, p, p, l, i, c, a, t, i, o, n
boolean flag = true;
// 중복 검사 + flag
// application
// 배열 : [a, p, p, l, i, c, a, t, i, o, n]
// 화면 : a, p, l, i, c, t, o, n
for(int j=0; j<i; j++) { // 중복 검사용 for문
if(str[i] == str[j]) {
flag = false;
break;
}
}
if(flag) { // flag가 true인 경우 == 중복이 없었다라는 의미
if(i==0) { // 첫 바퀴인 경우
System.out.print(str[i]);
}
else {
System.out.print(", " + str[i]);
}
count++;
}
}
System.out.println("\n문자 개수 : " + count);
}



class ArrayPractice
public void practice14() {
Scanner sc = new Scanner(System.in);
System.out.print("배열의 크기를 입력하세요 : ");
String[] arr = new String[sc.nextInt()];
sc.nextLine();
int index = 0;
while (true) {
for (int i = index; i < arr.length; i++) {
System.out.print(i + 1 + "번째 문자열 : ");
arr[i] = sc.nextLine();
}
index = arr.length;
System.out.print("더 값을 입력하시겠습니까?(Y/N) : ");
char plus = sc.next().charAt(0);
if (plus == 'Y' || plus == 'y') {
System.out.print("더 입력하고 싶은 개수 : ");
String[] arr2 = new String[arr.length + sc.nextInt()];
sc.nextLine();
System.arraycopy(arr, 0, arr2, 0, arr.length);
arr = arr2;
} else if (plus == 'N' || plus == 'n') {
System.out.println(Arrays.toString(arr));
break;
} else {
System.out.println("잘못 입력하셨습니다.");
continue;
}
}
}

class PracticeRun
package edu.kh.array.practice;
public class PracticeRun {
public static void main(String[] args) {
ArrayPractice arrEx = new ArrayPractice();
arrEx.practice1(); // O
arrEx.practice2(); // O
arrEx.practice3(); // O
arrEx.practice4(); // O
arrEx.practice5(); // O
arrEx.practice6(); // O
arrEx.practice7(); // O
arrEx.practice8(); // O
arrEx.practice9(); // O
arrEx.practice10(); // O
arrEx.practice11(); // O
arrEx.practice12(); // O
arrEx.practice13(); // O
arrEx.practice14(); // O
}
}