프로그래밍 언어 공부/Java 기초

[Java 스터디 첫 번째] 배열

always-dev 2022. 7. 17.
반응형

자바 스터디를 진행하고 있습니다.
개인적으로 공부한 내용을 바탕으로 정리하고 있으며
이상한 부분은 댓글에 남겨주시면 감사하겠습니다. 👍




1-1.배열의 선언과 생성

 

1-1-2. 배열의 선언이란 ?

배열을 다루기 위하여 참조변수를 선언하는 것이다.

타입[] 변수이름;

int[] arr;

 

1-1-3. 배열의 생성이란 ?

실제 메모리에 저장공간을 생성하기 위한 것 입니다.

 

배열을 생성하기 위해서는 연산자 new와 함께 배열의 타입과 길이를 지정해 주어야 합니다.

 

밑에는 배열 생성 예제입니다.

변수이름 = new 타입[길이];

arr = new int[4];

 

이 두 가지 (선언, 생성)이 완료 됐을 때 배열에 값을 저장하거나 읽어올 수 있게 된다.

 

밑에 예제는 배열의 선언과 생성을 한 것이며 '길이가 5인 배열' 혹은 '배열 arr'이라고 부른다.

변수이름 = new 타입[길이]; // 배열을 생성 (실제 저장공간을 생성)

int[] arr = new int[5];




1-2. 배열의 초기화

 

배열 초기화를 왜 하더라 ??

 

전에 다른 프로그램에 의해 저장된 쓰레기 값이 남아 있을 수도 있기 때문이다.

 

배열은 생성과 동시에 자동적으로 자신의 타입에 해당되는 기본값으로 초기화 된다.

 

밑에 예시를 봐보자.

초기화를 해주지 않고 배열을 선언하고 생성만 하였는데 0 0 0 0 0으로 출력이 된다.

이로써 배열은 생성과 동시에 기본값으로 초기화 됨을 알 수 있다.

int[] arr = new int[5];

for (int i : arr) {
    System.out.print(i + " ");
}

// 출력 : 0 0 0 0 0

 

 

 

 

그러면 무조건 자동으로 초기화를 시켜야만 하는걸까 ??

 

배열은 우리가 직접 배열 생성과 동시에 초기화 시킬 수 있다.

밑에 어떤 방법들이 있는지 코드를 봐보자.

// 밑에 두 가지 방법 다 같은 결과를 갖는다.
int[] arr = new int[]{ 1, 2, 3, 4, 5 };
int[] arr = { 1, 2, 3, 4, 5 };

이렇게 배열을 여러가지 방식으로 초기화 해줄 수 있다.




배열을 선언하고 생성하고 자동 초기화가 아닌 우리가 직접 초기화도 시켜주었다.

 

이제 배열을 어떤 식으로 출력할 수 있을지 알아보자.

1-3. 배열의 출력

 

배열 출력에는 여러 방법이 있다.
for문을 이용하거나 Arrays.toSring()메서드를 사용해도 좋습니다.

 

이 때 두 방식의 결과는 같습니다.

 

각각 예제를 통해서 어떤 식으로 사용하는지 알아봅시다.

먼저 for문은 인덱스와 상향된 for문을 이용할 수 있습니다.

int[] arr = { 1, 2, 3, 4, 5};

// 인덱스를 이용
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

// 상향된 for문을 이용
for (int i : arr) {
    System.out.println(i);
}

이번에는 Arrays.toString() 메서드를 사용하는 방법입니다.

int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(Arrays.toString(arr));

가끔가다가 메서드를 사용하지 않고 곧바로 배열을 출력하려고 하는데

실제 참조변수는 값을 향하는 것이 아니라 주소를 갖고 있기 때문에 주소가 출력됩니다.

 

 

밑에 잘못된 예시를 보겠습니다.

int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr); // I@123jfvb와 같은 형식의 문자열이 출력됩니다.

재미있는 것은 주소가 출력될 때 그 배열의 타입을 알 수 있습니다.

 

위와 같이 int[] 배열로 선언된 arrint타입의 배열로

I @ 123jfvb가 출력되게 됩니다. 이 주소의 형식은 타입@주소Iint를 의미하고 있습니다.

 

하지만 예외적으로 char배열은 println메서드로 출력하면 각 요소가 구분자없이 그대로 출력됩니다.

char[] chArr = {'a', 'b', 'c', 'd'};
System.out.println(chArr);
// abcd가 출력된다.




1-4. 배열의 복사

 

 

배열은 한번 생성하면 그 길이를 변경할 수 없다.
때문에 더 큰 공간을 위해서는 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야한다.



1-4-1. 배열 복사법 - for문

아래와 같이 for문을 이용하여 배열을 복사할 수 있다.

int[] arr = new int[5];

int[] tmp = new int[arr.length * 2];

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

하지만 이러한 작업은 비용이 많이 든다.

 

때문에 아래와 같이 두 번째 배열 복사법을 사용하는 것이 더 낫다.

 

 

 

1-4-2. 배열 복사법 - System.arraycopy()

 

System클래스의 arraycopy()를 사용하면 보다 간단하고 빠르게 배열을 복사할 수 있다.


  • for문은 배열의 요소 하나하나에 접근해서 복사하지만
  • arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사한다.
    • 각 요소들이 연속적으로 저장되어 있다는 배열의 특성때문에 이렇게 처리하는 것이 가능하다.

 

이제 이전 예제를 다음과 같이 수정할 수 있다.

int[] arr = new int[5];

int[] tmp = new int[arr.length * 2];

System.arraycopy(arr, 0, tmp, 0, arr.length);

arr = tmp;




1-5. String 배열

배열의 타입이 String인 경우에도 위에서 선언한 int배열과 별반 다를게 없다.

 

곧장 String 배열을 선언 및 초기화해보자.

String name = new String[4] { 집돌이, 집순이, 공돌이, 공순이 };

하지만 다르다고 할 수 있는 점이 있다.

 

먼저 참조변수 name이 실제 객체가 아닌 객체의 주소를 갖고 있음은 똑같다.

 

하지만 int 타입의 배열은 참조변수에 있는 객체의 주소를 따라가면 곧바로 실제 객체가 나오지만

String 타입의 배열은 실제  객체가 아닌 또 다시 객체의 주소를 가지고 있다.

 

정리하자면,
int[]기본형 배열이고
String[]참조형 배열이라고 말한다.




우리는 계속해서 문자열을 저장할 때 String을 사용해왔다.

 

당연히 문자를 모이면 문자열이 되니까 우리는 char이 아닌 String을 당연하게 사용했다.

 

 

 

근데 굳이 char로만 사용해도 되는데 왜 String으로 사용하는지 생각해본 적이 있을까?

 

한번 이 부분에 대해서 생각해보는 시간을 가져보자.

2. char 배열과 String 클래스 🚀

 

 

 

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

 

 

 

잠시 먼 옛날 이야기를 하면서 언제부터 이렇게 사용하게 되었는지 알아보자.

 

객체지향개념이 나오기 전에는 데이터와 기능이 따로 나눠져 있었다.

하지만 객체지향개념이 나오면서 데이터와 그와 관련된 기능을 하나의 클래스에 묶어서 사용할 수 있게 되었다.

 

즉, 서로 관련 있는 데이터와 기능을 묶을 수 있게 되었다.

 

위 글을 읽다보니 기능이라는 말이 있는데 얘기하지 않아도 이것이 함수라는 것을 알 것이다.
그럼 메서드는 무엇인가?

메서드는 객체지향 언어에서 대신 사용하는 용어일 뿐 함수와 같은 뜻이다.



 

2-1. char배열과 String 클래스의 차이점

String객체(문자열)은 읽을 수만 있지 변경이 불가능하다.

 

근데 우리는 항상 변경해왔던거 같은데..? 밑에 예제를 보자.

String str = "JAVA";
str += "8";
System.out.println(str); // "JAVA8" 이 출력된다.

정상적으로 출력되는데 왜 변경이 불가능하다고 하는 걸까?

 

사실 문자열에 "8"이 이어져서 나오는 것 같겠지만 새로운 내용의 문자열이 생성되는 것이다.

 

JAVA에 8이 붙어서 JAVA8이 되는 것이 아니라 곧 바로 JAVA8이라는 새로운 문자열을 생성한다.

 

이런 식으로 String + ""를 반복한다면 계속해서 새로운 문자열을 생성해야하기 때문에 비용이 많이 들게 된다.

알고리즘 문제를 풀면서 알고 있는 사람들이 많겠지만 문자열을 새로 생성하지 않고 문자열을 다루기 위해서는 StringBuffer 클래스를 사용하면 된다.



2-2. char배열과 String 클래스의 변환

가끔 char배열을 String 클래스로 변환하거나 그 역의 상황을 맞이하곤 한다.

밑에 예제를 보면서 어떤 식으로 변환하는지 알아보자.

먼저 char배열 -> String 일 때의 변환 예제이다.

char[] chArr = { 'A', 'B', 'C' };
String str = new String(chArr); // char배열 -> String

다음은 String -> char배열 일 때의 변환 예제이다.

String str = "ABC";
char[] tmp = str.toCharArray(); // String을 char배열로 변환
 
반응형

댓글