자바의정석

자바(Java) - 배열(Array)

백코딩 2023. 9. 19. 16:46
728x90
import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    String str = "안녕하세요";
    char ch = str.charAt(3);
    System.out.println(ch);
  }
}

ch1. 배열이란?

같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 '배열(array)'이라고 한다.

"배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것"

여기서 중요한 것은 '같은 타입'이어야 한다는 것이며, 서로 다른 타입의 변수들로 구성된 배열은 만들 수 없다.

 

int[] score = new int[5];

변수와 달리 배열은 각 저장공간이 연속적으로 배치되어 있다는 특징이 있다. 또한 변수의 선언과 달리 다뤄야 할 데이터의 수가 아무리 만ㅎ아도 단지 배열의 길이만  바꾸면 된다.

 

ch2. 배열의 선언과 생성

배열을 선언하는 방법은 간단하다. 원하는 타입의 변수를 선언하고 변수 또는 타입에 배열임을 의미하는 대괄호[]를 붙이면 된다. 대괄호[]는 타입 뒤에 붙여도 되고 변수이름 뒤에 붙여도 된다.

 

배열의 생성

배열을 선언한 다음에는 배열을 생성해야 한다. 배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고, 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어지는 것이다. 배열을 생성하기 위해서는 연산자 'new'와 함께 배열의 타입과 길이를 지정해 주어야 한다.

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

 

ch3 . 배열의 인덱스

생성된 배열의 각 저장공간을 '배열의 요소(element)'라고 하며, '배열이름[인덱스]'의 형식으로 배열의 요소에 접근한다. 인덱스(index)는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용된다.

"인덱스(index)의 범위는 0부터 "배열길이-1까지"

 

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

자바에서는 자바 가상 머신(JVM)이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있다. 배열은 한번 생성하면 길이를 변경할 수 없기 때문이 , 이미 새성된 배열의 길이를 변하지 않는다. 따라서 '배열이름.length'는 상수다.즉, 값을 읽을 수만 있을 뿐 변경할 수 없다.

class Main{
  public static void main(String[] args) {
    int[] score = new int[5];

    for(int i = 0; i < 6; i++){
      System.out.println(score[i]);
    }
  }
} // ArrayIndexOutOfBoundsException 에러




class Main{
  public static void main(String[] args) {
    int[] score = new int[5];

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

for문의 조건식에 배열의 길이를 직접 적어주는 것보다 '배열이름.length'를 사용하는 것이 좋다. '배열이름.length'는 배열의 길이가 변경되면 자동적으로 변경된 배열의 길이를 값으로 갖기 때문에, 배열과 함께 사용되는 for문의 조건식을 일일이 변경해주지 않아도 된다.

 

ch5. 배열의 초기화

배열의 생성과 동시에 자동적으로 기본값(0)으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 된다.

class Main{
  public static void main(String[] args) {
    int[] a = new int[]{50, 60, 70, 80,90}; // 배열의 생성과 초기화를 동시에
    int[] b = {50,60,70,80,90}; // new int[]를 생략할 수 있음
    
    int[] c;
//    c = {50, 60, 70,80, 90} new int[]를 생략할 수 없음
    c = new int[]{50,60,70,80,90};
    }
  }
}

ch6. 배열의 출력

class Main{
  public static void main(String[] args) {
    int[] arr = {100, 95,80,70,60};
    for(int i = 0; i < arr.length; i++){
      System.out.print(arr[i]+",");
    }
  }
}
import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] arr = {100, 95,80,70,60};
    System.out.println(Arrays.toString(arr));
  }
}

Arrays.toString(배열이름) 메서드는 배열의 모든 요소를'[첫번째 요소, 두번쨰 요소, ...]' 와 같은 형식의 문자열로 만들어서 반환한다.

자바에서 배열 객체를 직접 'System.out.println()'으로 출력하려고 하면, 배열 객체의 메모리 주소가 출력됩니다. 즉 배열의 실제 내용이 아닌 참조 주소가 출력됩니다.

 

'Arrays.toString()'메서드는 배열의 각 요소를 순회하며 각 요소의 'toString()' 메서드를 호출(원시 타입의 경우에는 해당 타입의 문자열 표현)하여, 배열의 모든 요소들을 읽기 쉬운 문자열 형태로 합쳐주므로, 배열의 실제 내용을 보고자 할 때 이 메서드를 사용합니다.

 

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] iArr1 = new int[10];
    int[] iArr2 = new int[10];
//    int[] iArr3 = new int[]{100,90, 80, 70, 60};
    int[] iArr3 = {100, 95,80,70,60};
    char[] chArr ={'a', 'b','c','d'};

    for(int i = 0; i < iArr1.length; i++){
      iArr1[i] = i + 1;
    }

    for(int i = 0; i < iArr2.length; i++){
      iArr2[i] = (int)(Math.random() *10) + 1;
    }

    for(int i =0; i< iArr1.length; i++){
      System.out.print(iArr1[i]+ ",");
    }
    System.out.println();

    System.out.println(Arrays.toString(iArr2));
    System.out.println(Arrays.toString(iArr3));
    System.out.println(Arrays.toString(chArr));
    System.out.println(iArr3); / 실행할 때마다 달라질 수 있다.
    System.out.println(chArr);
  }
}
// 총합 / 평균 구하기

class Main{
  public static void main(String[] args) {
    int sum = 0;
    float average  = 0f;

    int[] score = {100,88, 100, 100, 90};

    for(int i = 0; i < score.length; i++){
      sum = sum + score[i];
    }

    average  = sum / (float)score.length;

    System.out.println(sum);
    System.out.println(average);
  }
}

478 / 5 -> 95

478 / (float)5 -> 478 / 5.0f -> 478.0f / 5.0f -> 95.6f

이때 int 타입과 int 타입 간의 연산은 int 타입으로 결과로 얻기 때문에 정확한 평균값을 얻지 못하므로 score.length를 float 타입으로 변환하여 나눗셈을 하였다.

class Main{
  public static void main(String[] args) {
    int[] score = {79, 88, 91, 33, 100, 55, 95};

    int max = score[0];
    int min = score[0];

    for(int i = 1; i < score.length; i++){
      if(score[i] > max){
        max = score[i];
      } else if(score[i] < min){
        min = score[i];
      }
    } // end of for

    System.out.println("최대값 : " + max);
    System.out.println("최소값 : " + min);
  } // end of main
} // end of class

반복문을 통해서 배열의 두 번째 요소 'score[1]'부터 max와 비교하기 시작한다. 만일 배열에 담긴 값이 max에 저장된 값보다 크다면, 이 값을 max에 저장한다. 최소값도 같은 방식이다. 

 

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] numArr = {0,1,2,3,4,5,6,7,8,9};
    System.out.println(Arrays.toString(numArr));

    for(int i =0; i < numArr.length; i++){
      int n = (int)(Math.random() * 10);
      int temp = numArr[0];
      numArr[0] = numArr[n];
      numArr[n]  = temp;
    } // 첫 번째 요소를 두고 계속 랜덤을 배정
    System.out.println(Arrays.toString(numArr));
  }
}

random() 을 이용해서 배열의 임의의 위치에 있는 값과 배열의 첫 번째 요소를 뒤섞게 한다.

 

로또 번호 만들기

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] ball = new int[45];

    for(int i = 0; i < ball.length; i++){
      ball[i] = i + 1;
    }
    System.out.println(Arrays.toString(ball)); // 1 ~ 45까지 작성

    int tmp = 0;
    int j = 0;

    for(int i = 0; i < 6; i++){
      j = (int)(Math.random() * 45);
      tmp = ball[i];
      ball[i]  = ball[j];
      ball[j] = tmp;
    }

    System.out.println(Arrays.toString(ball));  // 바뀐 값

    for(int i = 0; i < 6; i++){
      System.out.printf("ball[%d]= %d\n", i, ball[i]);
    }
  }
}

 

ch12. String배열의 선언과 생성

배열의 타입이 String인 경우에도 int배열의 선언과 생성 방법은 다르지 않다. 

String[] name = new String[3];

3개의 String타입의 참조변수를 저장하기 위한 공간이 마련되고 참조형 변수의 기본값은 null이므로 각 요소의 값은 null로 초기화된다.

* null은 어떠한 객체도 가리키고 있지 않다는 뜻이다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
//    String[] name = new String[3];
//    String[] name = new String[]{"kim", "Park", "Yi"};
    String[] name = {"kim", "Park", "Yi"};

    name[0] = "kim";
    name[1] = "park";
    name[2] = "yo";

    System.out.println(Arrays.toString(name));
  }
}

ch14. 클래스

문자열을 저장할 때 String 타입의 변수를 사용했다.  사실 문자열이라는 용어는 '문자를 연이어 늘어놓은 것'의미하므로 문자배열인 char배열과 같은 뜻이다.  자바에서는 char배열이 아닌 String 클래스를 이용해서 문자열을 처리하는 이유는 String클래스가 char 배열에 여러 가지 기능을 추가하여 확장한 것이기 때문이다.

* String 클래스는 char 배열에 기능(메서드)을 추가한 것이다.

 

char 배열과 String 클래스의 한 가지 중요한 차이가 있는데, String객체(문자열)는 읽을 수 만 있을 뿐 내용을 변경할 수 없다는 것이다.

String str = "Java";
str = str + "8";
System.out.println(str);

위의 문자에서 문자열 str의 내용이 변경되는 것 같지만, 문자열은 변경할 수 없으므로 새로운 내용의 문자열이 생성된다.

* 변경 가능한 문자열을 다루려면, StringBuffer클래스를 사용하면 된다.

이러한 동작은 String 객체의 불변성을 유지합니다, 즉 한번 생성된 String 객체의 내용은 변경될 수 없습니다. 변경하려고 하면 항상 새로운 String 객체가 생성됩니다.

 

ch 15. String 클래스의 주요 메서드

String 클래스는 상당히 많은 문자열 관련 메서드들을 제공한다. 

char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
int length() 문자열의 길이를 반환합니다.
String substring(int from, int to) 문자열에서 해당 범위(from ~ to)의 문자열을 반환한다.(to는 포함 안 됨)
boolean equals(Object obj) 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false
char[] toCharArray() 문자열을 문자배열(char[])로 변환해서 반환한다.

charAt메서드는 문자열에서 지정된 index에 있는 한 문자를 가져온다. 배열에서 '배열이름[index]'로 index에 위치한 값을 가져오는 것과 같다고 생각하면된다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    String str = "안녕하세요";
    char ch = str.charAt(3);
    System.out.println(ch);
  }
}

 

substring()은 문자열의 일부를 뽑아낼 수 있다. 주의할 것은 범위의 끝은 포함되지 않는다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    String str = "안녕하세요";
    String sub = str.substring(1, 4);
    System.out.println(sub);
  }
}

equlas()는 문자열의 내용이 같은지 다른지 확인하는데 사용한다. 기본형 변수의 값을 비교하는 경우 '==' 연산자를 사용하지만, 문자열의 내용을 비교할 때는 equals()를 사용해야 한다. 그리고 이 메서드는 대소문자를 구분한다는 점에 주의하자.

대소문자를 구분하지 않고 비교하려면 equals() 대신 equalsIgnoreCase()를 사용해야 한다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    String str = "1234";

    if(str.equals("1234")){
      System.out.println("같은 내용입니다.");
    }
  }
}

커맨드 라인 입력(터미널)

ch18. 2차원 배열의 선언

2차원 이상의 배열, 즉 다차원 배열도 선언해서 사용할 수 있다. 메모리의 용량이 허용하는 한, 차원의 제한은 없지만, 주로 1, 2차원 배열이 사용되므로 2차원 배열만 잘 이해하고 나면 3차원 이상의 배열도 어렵지 않게 다룰 수 있다.

 

타입[][] 변수이름; int[][] score;
타입 변수이름[][]; int score[][];
타입[] 변수이름[] int[] score[];

*3차원 이상의 고차원 배열의 선언은 대괄호[]의 개수를 차원의 수만큼 추가해 주기만 하면된다.

 

int[][] socre= new int[4][3] // 4행 3열

실제로는 배열요소의 타입인 int의 기본값 0이 저장된다. 배열의 각 요소에는 배열요소 타입의 기본값이 자동적으로 저장된다.

 

ch19. 2차원 배열의 인덱스

2차원 배열은 행(row)과 열(column)로 구성되어 있기 때문에 index도 행과 열에 각각 하나씩 존재한다. '행index'의 범위는 '0 ~ 행의 길이 -1'이고 '열 index'의 범위는 '0 ~ 열의 길이 -1'이다. 그리고 2차원 배열의 각 요소에 접근하는 방법은 '배열이름[행 index][열index]이다.

 

ch20. 2차원 배열의 초기화

2차원 배열도 괄호[]를 사용해서 생성과 초기화를 동시에 할 수 있다. 다만, 1차원 배열보다 괄호[]를 한번 더 써서 행별로 구분해준다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
//    int[][] arr = new int[][]{{1,2,3}, {4,5,6}};
//    int[][] arr = {{1,2,3}, {4,5,6}};
    int[][] arr = {
        {1,2,3},
        {4,5,6}
      };
  }
}
import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[][] score = {
        {100,100,100},
        {20,20,20},
        {30,30,30},
        {40,40,40},
      };
    
    int sum = 0;

    for(int i = 0; i<score.length; i++){
      for(int j =0; j<score[i].length; j++) {
        System.out.printf("score[%d][%d] = %d\n", i, j, score[i][j]);

        sum += score[i][j];
      }
    }
    System.out.println("총합 : " + sum);
  }
}

2차원 배열은 '배열의 배열'로 구성되어 있다. 즉, 여러 개의 1차원 배열을 묶어서 또 하나의 배열로 만든 것이다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[][] score = {
        {100,100,100},
        {20,20,20},
        {30,30,30},
        {40,40,40},
        {50,50,50}
      };

    int korTotal =0, engTotal = 0, mathTotal = 0;

    System.out.println(" 번호 국어 영어 수학 총점 평균 ");
    System.out.println("===============================");

    for(int i = 0; i < score.length; i++){
      int sum = 0;
      float avg = 0.0f;

      korTotal += score[i][0];
      engTotal += score[i][1];
      mathTotal += score[i][2];

      System.out.printf("%3d", i + 1);

      for(int j = 0; j<score[i].length; j++){
        sum += score[i][j];
        System.out.printf("%5d", score[i][j]);
      }

      avg = sum/(float)score[i].length;
      System.out.printf("%5d %5.1f%n", sum, avg);
    }
    System.out.println("=======================");
    System.out.printf("총점 : %3d %4d %4d%n", korTotal, engTotal, mathTotal);
  }
}
import java.util.Scanner;

class Main{
  public static void main(String[] args) {
    String[][] words = {
        {"chair", "의자"},
        {"compoter", "컴퓨터"},
        {"integer", "정수"},
    };

    Scanner scanner = new Scanner(System.in);

    for(int i = 0; i < words.length; i++){
      System.out.printf("Q%d. %s의 뜻은?", i+1, words[i][0]);

      String tmp = scanner.nextLine();

      if(tmp.equals(words[i][1])){
        System.out.printf("정답입니다.%n%n");
      } else{
        System.out.printf("틀렸습니다. 정답은 %s입니다.%n%n", words[i][1]);
      }
    }
  }
}

ch24. Arrays로 배열 다루기

Arrays클래스는 배열을 다루는데 유용한 메서드를 제공한다.

배열의 비교와 출력 - equals(), toString()

 

toString() 배열의 모든 요소를 문자열로 편하게 출력할 수 있다. toString()은 일차원 배열에만 사용할 수 있으므로, 다차원 배열에느느 deepToString()을 사용해야 한다. deepToString()은 배열의 모든 요소를 재귀적으로 접근해서 문자열을 구성하므로 2차원 뿐만 아니라 3차원 이상의 배열에도 동작한다.

 

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] arr = {0,1,2,3,4};
    int[][] arr2D = {{11,12},{21,22}};

    System.out.println(Arrays.toString(arr));
    System.out.println(Arrays.deepToString(arr2D));
    
  }
}

equals()는 두 배열에 저장된 모든 요소를 비교해서 같은면 true, 다르면 false를 반환한다. equals()도 일차원 배열에만 사용 가능하므로, 다차원 배열의 비교에는 deepEquals()를 사용해야 한다.

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    String[][] str2D = new String[][]{{"aaa", "bbb"},{"ccc", "ddd"}};
    String[][] str2D2 = new String[][]{{"aaa", "bbb"},{"ccc", "ddd"}};

    System.out.println(Arrays.equals(str2D, str2D2));
    System.out.println(Arrays.deepEquals(str2D, str2D2));
  }
}

배열의 복사 - copyOf(), copyOfRange()

copyOf()는 배열 전체를, copyOfRange()는 배열의 일부를 복사해서 새로운 배열을 만들어 반환한다. 늘 그렇듯이 copyOfRange()에 지정된 범위의 끝은 포함되지 않는다.

 

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};
    int[] arr1 = Arrays.copyOf(arr, arr.length);
    int[] arr2 = Arrays.copyOf(arr, 3);
    int[] arr3 = Arrays.copyOf(arr, 7);
    int[] arr4 = Arrays.copyOfRange(arr, 2,4);
    int[] arr5 = Arrays.copyOfRange(arr, 0,7);



    System.out.println(Arrays.toString(arr1));
    System.out.println(Arrays.toString(arr2));
    System.out.println(Arrays.toString(arr3));
    System.out.println(Arrays.toString(arr4));
    System.out.println(Arrays.toString(arr5));
  }
}

 

배열의 정령 - sort()

배열을 정렬할 때는 sort()를 사용한다. 

import java.util.Arrays;

class Main{
  public static void main(String[] args) {
    int[] arr = {1,2,4,5,1,2};
    Arrays.sort(arr);

    System.out.println(Arrays.toString(arr));
  }
}
728x90

'자바의정석' 카테고리의 다른 글

자바(Java) - 객체지향 언어(2)  (0) 2023.09.21
자바(Java) - 객체지향 언어(1)  (0) 2023.09.20
변수(Variable)  (1) 2023.09.14