2023.01.20 - 안드로이드 앱개발자 과정

CHA·2023년 1월 24일
0

JAVA



1차원 배열 Array - Premitive 배열


  • 기본형 배열의 생성 : 배열도 객체!

    데이터타입[] 참조변수 이름 = new 데이터타입[배열의크기]

java 에서 배열은 '객체' 입니다. 앞서 우리가 객체를 생성할 때, new 연산자를 이용하여 클래스의 인스턴스를 생성해주고, 그 주솟값을 참조변수에 담아 사용하였습니다. 배열도 마찬가지 입니다. 자, 다음과 같이 int 형 3개짜리 배열객체를 생성해보겠습니다.
int[] arr = new int[3];
arr 라는 이름을 가진 int[] 형 '참조변수' 하나와 크기가 3인 배열객체 '1개' 를 생성했습니다.

Q . 참조변수의 주솟값은 곧 객체의 주소일까? 만약 그렇다면 배열의 시작주소가 객체의 주소와 같을까?

-> 참조변수의 주솟값은 객체의 주소가 맞다고 볼 수 있습니다. 다만, 시작주소가 아닌, 객체의 멤버변수의 주소가 될 가능성이 매우 높습니다. 추가적으로 객체 내부적으로는 메소드의 주소가 직접적으로 존재하지 않고, 함수테이블표의 주솟값을 가지고 있는 참조변수가 존재합니다. 이 참조변수를 통해 함수테이블표의 메소드에 접근할 수 있습니다.

System.out.println(arr); // 배열객체의 .toString()이라는 기능이 자동 발동함.
출력결과 : [I@1ee0005 : I (int) [(배열) ee0005(객체 고유번호) --> hashcode
  • 배열의 값

    • 배열요소의 값
      다음 코드를 봅시다.
    System.out.println(arr[0]);
     System.out.println(arr[1]);
     System.out.println(arr[2]);
     // System.out.println( arr[3] ); // error
     출력결과 : 0 / 0 / 0

    배열을 생성하게 되면 0으로 모든 배열 요소들이 초기화됩니다. C언어에서는 배열 인덱스를 벗어난 곳의 값을 출력하려 하면 쓰레기 값이 출력이 되었으나, 자바에서는 컴파일 오류를 띄웁니다.

    배열의 값을 대입하고 싶다면 다음 코드와 같이 할 수 있습니다.

    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;

    추가로 변수를 통해 값을 대입할 수도 있습니다.

    int num1 = 10;
    arr[0] = num1;
    arr[1] = num1 + 10;
    arr[2] = num1 * 3;
  • 참조변수 대입
    배열 참조변수 끼리도 대입이 가능합니다.

    double arr1 = new double[] { 3.14, 2.48, 7.23 };
    double arr2 = arr1;

    이는 객체의 대입이 아니라 주솟값을 복사했을 뿐입니다. 즉, 객체는 1개이며 이 1개의 객체를 공유하는 형태 입니다. 그렇기 때문에 한쪽 배열 요소의 값이 변경된다면 다른 한쪽 배열의 요솟값 또한 변경됩니다.

  • 배열 초기화

    • 생성시 초기화
      배열 객체를 생성하면서 배열 요소값들을 초기화 할 수 있습니다.
      int[] arr = new int[] { 10,20,30 };
      그리고 new 를 통해 배열 객체를 생성 시에 배열 개수를 지정해주어야 하는데, 오히려 오류를 만들어낼 가능성이 존재하기 때문에 초기화를 했다면 그럴 필요 없습니다. 그래서 자바에서는 초기화시 요소값을 넣었을 때, 배열 갯수를 지정하면 컴파일 오류를 띄웁니다.

    • 축약 표현
      배열에서는 String 클래스와 마찬가지로 축약 표현이 있습니다.
      int[] arr = { 100,200,300 }
      자동 new int[ ] 를 해주어 좀 더 편리하게 배열 초기화가 가능합니다.

      Q . 배열도 String 과 마찬가지로 string constant pool 과 같은 메모리 공간에 올라갈까?
      -> 형변환시 컴파일러가 자동으로 처리해주는것 처럼, 배열에서의 자동 new 처리도 자동으로 처리됩니다. String 의 처리방식과는 차이가 있습니다.

    • 변수로 초기화
      배열 생성시 갯수지정을 상수가 아닌 변수로 지정할 수 있으며, 배열객체의 초기화시 변수로 값도 지정 가능합니다.

      // 변수로 갯수지정
      int num = 10;
      int[] arr = new int[num]; // 배열 개수는 10.
      
      // Scanner 를 통한 갯수지정
      Scanner sc = new Scanner(System.in);
      int num = sc.nextInt();
      int[] arr = new int[num];
      
      // 변수로 값 지정
      int num = 10;
      int[] arr = new int[] { num , num + 1, num + 2};

1차원 배열 Array - Reference 배열


  • 참조형 배열의 생성

    참조형 배열을 생성하는 법은 기본형 배열 때와 크게 다르지 않습니다. 다음 형식으로 참조형 배열을 생성합니다.
    (데이터타입) 참조변수 이름 = new (데이터타입)[배열개수];

    예제 코드를 보겠습니다.
    String[] strArr = new String[3];

    위 코드는 String 참조변수를 3개 담을 수 있는 String 타입의 배열객체를 생성한 코드 입니다. 여기서 중요한 부분은 참조형 배열은 객체를 여러개 담는 배열이 아니라는 사실입니다. 참조형 배열은 참조형 변수를 여러개 담을 수 있는 배열입니다. 썩 이해가 잘 안되니 예를 들어 보겠습니다.

    자, 객체가 있습니다. 근데 그 객체가 한 100개정도 있다고 생각해봅시다. 앞서 객체들을 관리하기 위해서는 참조변수가 필요하다고 했습니다. 그러면 각 객체를 관리하기 위해서는 참조변수가 100개가 필요할겁니다. 근데 100개의 참조변수는 관리하기도 불편하고 너무 많아보입니다. 그래서 우리는 참조형 배열을 이용합니다. 기본형 배열이 여러개의 값들을 편리하게 이용하기 위해 만들어졌듯, 여러개의 객체를 편리하게 이용하기 위해 만든것이 참조형 배열입니다. 또한 앞서 말했듯 참조형 배열은 참조변수를 위한 배열일 뿐, 객체가 배열요소가 되는것은 아니니 이 사실을 잊지맙시다.

  • 배열의 값

    그러면 이 참조형 배열에 값을 넣어보겠습니다. 앞서 활용했던 String 타입의 배열로 예를 들어봅시다.

    String[] strArr = new String[3];
    strArr[0] = new String["sam"];
    strArr[1] = new String["robin"];
    strArr[2] = "hong";

    표현 방식의 차이가 생겼을 뿐, 문자열의 값을 변수에 대입하는것과 별반 다를게 없습니다.
    strArr[0] = new String["sam"]; 은 참조형 배열 str 에 0번 인덱스 요소에 sam 이라는 문자열을 대입하는 코드입니다.
    즉, str 에 0번째 인덱스에 들어있는 참조형 변수(문자열 타입의 변수) 한개에 sam 을 대입한것 입니다. 그렇기 때문에 역시 자동 new 을 통한 문자열 대입도 가능합니다.

  • 배열의 기능메소드

    그러면 혹시 String 객체가 가지고 있는 메소드 들도 사용이 가능하지 않을까요? 맞습니다. 사용 가능 합니다. 다음 코드는 그 예제를 담고있습니다.

    중략...
    strArr[0] = "Hello";
    char ch = strArr[0].charAt[0];
    int len = strArr[0].length();
    출력결과 : H / 5
  • 배열 초기화

    • 생성시 초기화
      기본형 배열과 마찬가지로 생성 시 초기화 또한 가능합니다.
    String[] strArr1 = new String[] { new String("android"), new String("ios"), new String("web") };
    String[] strArr2 = { "android" , "ios" , "web" };

    추가적으로 앞서 기본형 배열의 경우, 초기화를 하지 않으면 기본값으로 0이 대입됩니다. 참조형 배열의 경우 0 이 아닌 null 값으로 초기화 됨을 참고합시다.

    • 변수로 초기화
    String str1 = "android";
    String str2 = "ios";
    String str3 = "web";
    String[] strArr = { str1, str2, str3 };
  • 클래스와 배열

    앞서 예제로 만들었던 코드들은 모두 String 객체의 참조변수들의 배열형태 였습니다. 하지만 참조변수는 String 객체의 주솟값 뿐아니라 사용자 정의 class 의 주솟값도 가질 수 있습니다. 물론 다른 클래스도 마찬가지 입니다. 아래 예시에서는 Person 클래스를 정의하고 이에 대한 참조형 배열을 만든 예제 입니다.

    class Person{
        String name;
        int age;
    
        void print() {
            System.out.println("이름 : " + name);
            System.out.println("나이 : " + age);
            System.out.println();
        }
    }
    
    public class Main{
        public static void main(String[] args){
        Person[] p = new Person[3];
        p[0] = new Person();
        p[0].name = "sam";
        p[0].age = 20;
        p[0].print();
    }
    // 출력결과 : sam / 20

    Person[] p = new Person[3]; 을 통해 Person 타입의 크기가 3인 참조형 배열을 선언하였습니다. 그리고 p[0] = new Person(); 을 통해 참조변수 하나를 Person 클래스의 객체의 주솟값을 담아두었습니다. 그리고 p[0].name = "sam"; 을 통해 Person 객체 하나의 멤버변수에 sam 문자열값을 넣어 주었습니다. 이처럼 사용자 정의 class 또한 참조변수를 통해 제어할 수 있음을 보여줍니다.

  • for-each 문

    기존의 for 문은 사실 예외가 일어날 가능성이 꽤나 높습니다. 특히 배열을 이용할때는 말이죠. for 문의 반복횟수, 반복조건, 초기화 조건등이 모두 포함되기 때문에 배열 인덱스 관리도 해주어야 하고 논리적인 오류가 일어날 가능성 또한 있습니다. 그래서 만들어진 문법이 for-each 문법입니다. 문법의 형태는 다음과 같습니다.

    for(반복변수 : 배열이름){
    실행문
    }

    예제를 보겠습니다.

    • 기본형 배열 for-each

      int[] nums = new int[] { 10, 20, 30 };
      for(int temp : nums){
      System.out.print(temp + " ");
      }
      // 출력결과 : 10 20 30
      
      double[] www = new double[] {3.14,2.56,8.79};
      for(double temp : www) {
      		   System.out.println(temp + "/");
      }
      // 출력결과 : 3.14/2.56/8.79
    • 참조형 배열 for-each

      	String[] strs = new String[] {"android","ios","web" };
      		for(String temp : strs) {
      		    System.out.println(temp + " ");
      		}
       // 출력결과 : android ios web

2차원 배열 Array


2차원 배열은 간단하게 훑고 넘어가겠습니다.

  • 2차원 배열이란?

    2차원 배열은 1차원 배열의 참조변수들을 여러개 가진 배열객체 입니다. 앞서 예시로 들었던 String 배열을 보겠습니다.
    String[] str = new String[3]; String 타입의 크기가 3인 배열 생성 코드 입니다. 여기서 String[] 은 String 타입의 배열임을 명시합니다. 2차원 배열도 마찬가지 입니다. int[][] 은 타입이 int[] 인 배열임을 명시하게 됩니다. 다음이 2차원 배열의 생성 형태 입니다.
    int[][] arr = new int[3][];

  • 2차원 배열 값

    2차원 배열은 앞서 말했듯, 1차원 배열의 주소값을 가질 수 있는 참조변수들을 모아놓은 배열객체 입니다. 따라서 다음과 같은 값 대입의 절차를 거칩니다.

    int[][] arr = new int[3][];
    
    arr[0] = new int[4];
    arr[1] = new int[2];
    arr[2] = new int[3];
    
    arr[0][0] = 10;
    arr[0][1] = 20;
    arr[0][2] = 30;
    .
    .
    .

    먼저 2차원 배열 객체를 생성해줍니다. 그리고 각각의 배열요소들, 즉, 1차원 배열의 참조변수들의 배열객체를 생성해줍니다. 그 이후에 1차원 배열객체의 각각의 배열 요소들에 값을 대입해줍니다.

    만일, 1차원 배열을 참조하는 참조변수들이 모두 같은 개수를 가진 배열 객체를 참조한다면, 다음과 같이 생성하는것도 가능합니다.
    int[][] arr = new int[3][4];
    이는 크기가 4인 1차원 배열을 참조하는 3개의 참조변수들의 배열을 생성한 것입니다.

    • 초기화
      2차원 배열의 초기화는 다음과 같습니다.
      int[][] arr = new int[][] { 
      			new int[] { 10, 20 }, 
      			new int[] { 10, 20, 30, 40 } 
      			};
      다만, 코드가 길고 복잡하기 때문에 자동 new 생성을 이용하여 다음과 같이 바꿀 수 있습니다.
      int[][] arr = { 
      			{ 10, 20 }, 
      			{ 10, 20, 30, 40 } 
      			};
  • 2차원 배열과 for-each 문

    다음 코드와 같이 for-each 문을 활용하여 2차원 배열을 이용할 수 있음을 참고합시다.

    int[][] arr = new int[2][3];
    for(int temp : arr){
        for(int temp2 : temp){
            System.out.print(temp2 + " ");
        }
        System.out.println();
    }
profile
Developer

0개의 댓글