language/java

5. 배열

wooweee 2023. 3. 3. 11:21
728x90

배열

  • array는 같은 type의 여러 변수를 하나의 묶음으로 다루는 것
  • 앞에 변수 part 에서 variable은 ram 의 일정부분을 사용하기위해서 이름을 지정해주는 것이라고 했음. 근데 저장하고 싶은 값이 너무 많음
  • int a= 1, int b= 2, ,,,,  ->  int[] num = {1,2,3,4,5,6,7};

 

배열의 선언과 생성
배열의 인덱스

 

타입[] 변수이름; // 배열을 선언(배열을 다루기 위한 참조변수 선언)
변수이름 = new 타입[배열길이]; // 배열을 생성(실제 저장공간 생성)

int[] score;
score = new int[5];
// score(0x100) -> score[0], score[1], score[2], score[3], score[4]

인덱스의 범위: 0 ~ 배열길이-1 

 

 

array 형식 쉽게 기억하기 with 값 저장하는 원리

type[] variable = new type[N];
int[] i = new int[5];
  • N: array의 값 개수 의미
  • variable: 배열을 다루는데 필요한 참조변수 일 뿐 값을 저장하기 위한 공간이 아님
  • new: 값을 저장하기 위해 사용
  • 대입연산자(우측->좌측 순서로 작동)는    new int[5]; 부터 읽고 i라는 참조변수를 지정
  • <기억법> array라는 참조형 type을 티내고 싶어서 [] 넣기      new로 array box 만들어주기   box 개수 정해주기 array니깐 [] 쓰기

참고

더보기
int[] i = new int[5];
  1. int[] 하는 이유: 그냥 int는 자료형 변수이기에 난 int인 array를 만들고 싶으므로 []넣어줘야함.
    •      int i [] 도 가능
  2. i : 변수 넣는것은 동일 변수가 우선 존재해야 나중에 값도 꺼내쓰고 값을 원하는 저장공간에 넣을 수도 있으니깐
  3. new int[5]: 자료형 변수와 달리 array이기에 실제 값을 넣을 수 있는 새로운 array box를 생성해줘야함 그게 new int 임.  [] 공간이 얼마나 필요한지 지정해줘야함. array형식이니깐 당연히 [ ]를 써서 표현

 

 


  • 중요 개념

 

int a = 1;

int a;
a = 1;
  • int a =1;  한 개의 memory공간을 차지. 그래서 a라고 이름도 붙여줌과 동시에 1이라는 값을 넣을 수 있다.
  • 주소와 공간을 동시에 작동이 가능.
    1. a라는 주소 넣고
    2. 기본형 값 0을 자동으로 가진 후 1이라는 값을 집어넣음
  • □ 상자 자체에 a라는 이름 지정 값도 넣는 것임

 

int[] i = new int[5];
  • 하지만 array 같은 경우는 값이 보편적으로 값이 2개 이상일 때 사용
  • 자료형처럼 □ box에 변수랑 값을 넣으려고 하는 것이 불가능
    1. new int[5] 를 보고 객체를 생성할 거구나 그리고 box 5개 달라네 해서(□□□□□) box들을 묶음 지음(연속적으로 배치).
    2. int[] i 를 보고 box의 묶음의 메모리 주소와 변수를 연결 i = 0x100 

 

** box마다 주소가 있을텐데 어떻게 주소하나로 변수와 연결함? 추측상 첫번째 box의 주소를 대표로 가져올 듯함. 그러니깐 변수 자체에 값을 넣지 못할 수 밖에 없는 듯

 

int[] a;
a = new int[5];

 

  • 나눠져 있을 때
    1. int[] a;  - []를 넣은 참조형 타입이 필요한 이유
      • 메모리 주소를 a라는 변수를 선언 :  소스파일상에선 막말로 text 그 이상 그 이하도 아님
      • 나중에 컴파일 시점에서 javac(compilter)가 해당 text를 읽고 a라는 변수에 int[]라는 메타 정보에 맞는 객체가 들어오는지 확인.
    2. a = new int[5]; 
      • 얘가 a에 들어가는 객체
      • new 생성자를 이용해서 객체 생성, int[5]]로 int 배열 초기화
      • 해당 객체 주소를 a의 값으로 넣는다.

 

 

  • 자주 하는 실수
    • 주소만 연결하고 box는 존재하지 않아서 int[1] =0; 값이 저장이 안됨. 넣을 공간이 없는데 결과 도출하려고 하니깐 error 
int[] a;
a = 1;
System.out.println(a[0]); // error

 


정리

int[] i = new int[5];
  • i라는 참조변수가 0x100이란 주소와 연결됬다고 하고 0x100이란 주소의 memory에 가보니깐 5칸을 차지하고 있음.
  • 5칸의 각각의 이름은 i[0] i[1] i[2] i[3] i[4] 라고 자동으로 만들어짐. * [] : index라고 하고 범위는 0부터 시작함
  • 현재 값이 없는데 이런 경우는 값을 기본형 값을 준다.

기본형 값 == 기본값

자료형 기본값
boolean false
char '\u0000'
byte, short, int 0
long 0L
float 0.0f
double 0.0d or 0.0
참조형 변수 null 대충 비었다는 뜻

 

배열의 길이(배열 이름.length)

int[] arr = new int[5];
int tmp = arr.length;
  • .length인 이유
    • 해당 object 변수인 경우 object.변수명 으로 값을 꺼낸다. length도 마찬가지다.
    • Array 객체가 만들어질 때 int length; 가 같이 만들어지기 때문 - JVM이 모든 배열의 길이를 별도로 관리하며 배열은 한번 생성하면 길이를 변경할 수 없기 때문에 배열이름.length는 상수이다.
    • https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.7 : 참고 문서
  • 추가 정보
    1. 배열의 길이            : .length
    2. String의 길이        : .length();
    3. Collection의 길이 : .size();

 

배열의 초기화
배열의 출력

// 배열 출력
int[] i = new int[3]; 
i[0] = 18; //array 값 넣기 자료형 변수랑 동일함 단지 []만 들어갔을 뿐
System.out.println(i[0]); // 추출 사용

// 추출말고 통채로 출력할 때 주의점
int[] i = {1,2,3};
System.out.println(i); // i는 참조변수로 주소만 가지고 있어서 주소가 출력됨
System.out.println(Arrays.toString(i)); // method를 통해서 array 값 출력 [1,2,3]

// 예외 상황인 char[]
char[] c = {'a', 'b', 'c'};
System.out.println(c); // 주소 말고 값(=요소) 출력 됨. abc
// println method가 char 배열일때만 이렇게 동작하도록 오버로딩 되어있다.

 

배열의 초기화

int[] i = {1,2,3,4,5}; // new int[] 생략가능

int[] i;
i ={1,2,3,4,5}; // error. new int[] 생략불가

짧게 쓰고 싶어 하는 목적으로 쓰는 거니깐 int[] i = {1,2,3,4,5}; 요거 대체로 쓴다고 함
int[] i; i = new int[] {1,2,3,4,5}; 거의 안씀

 

배열 복사

3가지 방법

  1. clone()
  2. for문
  3. System.arraycopy

 

  • System.arraycopy(num, i, newNum, j, num.length);
  • num[i]에서부터 num.length 개의 요소를  newNum[j] 인덱스부터 복사해서 넣기

 

배열 예제 

더보기
// Q1. 점수 15,50, 45, 95 의 합과 평균을 구해라
int 합=0;
float 평균= 0f;

int[] 점수 = {15, 50, 45, 95};

for(int i=0; i<점수.length; i++) {
    합 += 점수[i];
    평균 += (float)점수[i]/점수.length;
}
System.out.println(합);
System.out.println(평균);

// Q2. int[] num = {15, 50, 45, 95}; 의 최대값과 최소값을 구해라
int[] num = {15, 50, 45, 95};
int max = num[0]; //15
int min= num[0];  //15
for(int i=1; i<num.length; i++) {
    if(num[i]>max) max = num[i];
    else if(num[i]<min) min = num[i];
}
System.out.println(max);
System.out.println(min);

// Q4. [0,1,2,3,4,5] 값을 섞어라
int[] num = {0, 1, 2, 3, 4, 5};
for(int i=0; i<num.length; i++) {
    int randomNum = (int)(Math.random()*6); // 0~5 의 random 숫자
    // 이건 앞부분의 x,y 위치바꾸기 원리 사용
    int tmp = num[i]; 	     // tmp = x; 값 임시저장
    num[i] =num[randomNum];  // x=y; x값 y로 바꾸기
    num[randomNum] = tmp;    // y=tmp; 이전의 x 값을 tmp가 가지고 있으니깐
}
System.out.println(Arrays.toString(num));

Q3. 로또를 해보자
//1) lotto 는 45개 숫자 
int[] loNum = new int [45];
System.out.println(loNum.length); // 기본형 값이 0인 box 45개 

for(int i=0; i<loNum.length; i++) {
    loNum[i] = i+1;
}
System.out.println(Arrays.toString(loNum));

//2) random 추출 6개 
// loNum = {1,2,3,,,,45};
for(int i=0; i<6; i++) {
    int randomNum = (int)(Math.random()*45);
    int tmp = loNum[i];
    loNum[i] = loNum[randomNum];
    loNum [randomNum] = tmp; // 6개만 뽑는데 굳이 x,y 바꾸기 해주는 이유는 안바꿀 때 반복되는 수가 나올 수 있기 때
}
System.out.println(Arrays.toString(loNum));

//3) 6개만 보여주기 
for(int i=0; i<6; i++) {
    System.out.print(loNum[i] + ", ");
}

 

String 배열 선언과 생성

String은 class 여서 class의 규칙을 따라야 하지만 기본형 type 처럼 array 생성이 가능한 예외적인 class 이다.

String[] name = new String[2];
name[0] = "1";  // 원래 class 인 경우 new String("1"); 이렇게 해야 한다.
name[1] = "12";


String[] name1 = new String[] {"a", "b"}; // 잘 안씀

String[] name2 = {"a", "b"}; // new String[] 생략가능

String[] name3;
name3 = new String[] {"a", "b"}; // new String[] 생략불가

 

String class

  1. String class = char arrays + method
    • String class 덕분에 char array에 여러가지 기능을 추가하여 확장 사용이 가능
  2. 변경은 가능한데 default 가 변경 불가 - 메모리를 새로 만듬
String str = "java"; //0x100에 존재하는 것이 "java"
str = str + "8"; //0x200 에 존재하는 것이 "java8"
System.out.print(str);

 

String 주요 method

더 많은 String method: 2023.03.11 - [java/java 기초] - 9. java.lang 패키지와 유용한 클래스

// char charAt(int index) : String의 위치(index)에 있는 char를 반환, index는 0부터 시작
    String str = "1234";

    char ch = str.charAt(0);
    System.out.println(ch);


// int length : String의 길일 반환
    String str = "1234";

    int count = str.length();
    System.out.println(count);


// String subString(int from, int to) : String에서 from~to까지 String반환, 0부터 시작 to 미포함
    String str = "1234";

    String subString = str.substring(1,4);
    System.out.println(subString);


// boolean equals(Object obj) : String 내용이 같은지 확인 후 true false 반환
    String str = "1234";

    boolean check = str.equals("123");
    System.out.println(check);

    if(str.equals("1234")) {System.out.println("true");}


// char[]toCharArray() : String을 char[]로 변환 후 반환
    String str = "1234";

    char[] charArray = str.toCharArray();
    System.out.println(charArray); // char는 주소로 안나타남
    System.out.println(charArray[2]);
    System.out.println(Arrays.toString(charArray));

 

2차원 배열의 선언

3차원 이상 고차원도 2차원이랑 원리 같으므로 2차원까지만 알자

//선언 방법
    type[][] variableName;
    variableName = new type[3][2];
    
    int[][] columnraw = new int[3][2]; // 3행 2열 (가로 세줄 세로 두줄)

// 요소 넣기
    int[][] columnraw = new int[2][1];
    
    columnraw[0][0] = 1;
    columnraw[1][0] = 2;
    // 넣지 않은 값은 기본형 값 0으로 초기화
    
// 짧게 쓰기
int[][] columnraw = new int[][] {{1,2},{2,1}, {0,0}};
    
// new int[][] 생략가능
    int[][] columnraw ={
    {1,2},
    {2,1},
    {0,0}
    };

 

예문

더보기
Q1. {100, 100, 100}, {20, 20, 20}, {30, 30, 30}, {40, 40, 40} 합을 구하시오.

int[][] score = {
	    {100, 100, 100},
	    {20, 20, 20},
	    {30, 30, 30},
	    {40, 40, 40}
};
System.out.println(score.length); // column length

int sum =0;
for (int i = 0; i < score.length; i++) {
	for (int j = 0; j < score[i].length; j++) {
		int partScore = score[i][j];
		sum += partScore;
	}
}
System.out.println(sum);

/**
참고용- 변수의 위치의 중요성
*/
int[][] score = {
                  { 100, 100, 100}
                  , { 20, 20, 20}
                  , { 30, 30, 30}
                  , { 40, 40, 40}
                  , { 50, 50, 50}
                };
                
// column sum and average
// int sum = 0;
for(int i=0; i<score.length; i++) {
   int sum =0;
   float ROWLENGTH = (float)score[i].length;
   for(int j=0; j<ROWLENGTH; j++) {
       sum +=score[i][j]; // 100+0 +100+ 100
   }
System.out.printf("%d sum = %d%n", i, sum);
System.out.println(i + " average = " +sum/ROWLENGTH);
}
         
// subject sum
int korea = 0;
int english = 0;
int math = 0;
for(int i=0; i<score.length; i++) {
    korea += score[i][0];
    english += score[i][1];
    math += score[i][2];
}
System.out.println("korea: " + korea + " english: " + english + " math: " + math);
  • int sum; 이 안되는 이유, 값 자체가 없기 때문 - JS 의 undefined 와 동일
  • 참고: 변수 선언하고 초기화를 안하는 경우(외부 객체 불러오지 않고 main 안에서 직접 변수를 선언하고 사용하는 경우). 객체를 참조변수로 하는 변수 선언 후 초기화 하지 않은 값들은 자동 초기화가 된다.
더보기
// 외부 객체 불러오지 않고 main 안에서 직접 변수를 선언하고 사용하는 경우
public class Main {
    public static void main(String[] args) {
        // 해당 class 내에서 초기화 하지 않을 경우의 값
        int a;
        System.out.println(a); // error
    }

}
// 객체를 참조변수로 하는 변수 선언 후 초기화 하지 않은 값들은 자동 초기화가 된다.
public class Main {
    public static void main(String[] args) {
        Try try1 = new Try(); // 이때 자동 초기화가 된다.
        int a = try1.a;
        System.out.println("a = " + a); // 0
    }

}

class Try{
    int a;
}

 

Arrays

  • Array와 Arrays
    • Array: 배열의 길이가 고정되고 기본형부터 해서 모든 것을 받을 수 있다. 하지만 Method가 따로 존재하지 않는다.
    • Arrays: Array를 다루기 위해서 == Array 조작 기능을 가진 class 이다.
  • ArrayList
    • ArrayList: Array와 거의 동일하지만 배열의 길이가 가변상태이고 객체만 받는다. Method를 가지고 있어서 Arrays를 사용하지 않는다.
    • 객체만 받는다곤 하지만 오토박싱으로 인해서 자료형 값도 받을 수 있다. 하지만 type은 객체 type이다.

Arrays와 ArrayList 자세한 내용 : 2023.01.05 - [java/java 기초] - 11. collection framework 개념

// toString()
	int[] arr = {1,2,3};
	int[][] arr2D = {{1,2},{1,2}};
    
	System.out.println(Arrays.toString(arr));
	System.out.println(Arrays.deepToString(arr2D));
    
// equals()
    String[][] str2D =new String[][]{{"a","b"},{"1","2"}};
    String[][] str2D2 =new String[][]{{"a","b"},{"1","2"}};
    
    System.out.println(str2D == str2D2) // false
    System.out.println(Arrays.equals(str2D, str2D2));  // false. 1차원
    System.out.println(Arrays.deepEquals(str2D, str2D2)); // true. 다차원
    
// copyOf(variable, int) 배열 시작은 고정 끝이 달라짐
    int[] arr = {0,1,2,3,4};
    
    int[] arr2 = Arrays.copyOf(arr, arr.length);
    int[] arr3 = Arrays.copyOf(arr, 3); // 0~2까지의 index 가짐 [0,1,2]
    int[] arr4 = Arrays.copyOf(arr, 7); // 0~6까지의 index 가짐 [0,1,2,3,4,0,0]
    
// copyOfRange(variable, int from, int to) // array의 시작과 끝 추출 가능
    int[] arr5 = Arrays.copyOfRange(arr, 2, 4); // 2~3 index [2,3]
    int[] arr6 = Arrays.copyOfRange(arr, 0, 7); // 0~6 index [0,1,2,3,4,0,0] 
    
// sort(): 오름차순
    int[] arr = {1,4,2,3,0};
    Arrays.sort(arr);
    System.out.print(Arrays.toString(arr)) [0,1,2,3,4]

 

 

 

이전 발행글:  4. 조건문(if, switch) 반복문 (for, while)

 

다음 발행글 :  6. oop(object-oriented Programming) 객체지향 프로그래밍