5장 - 배열

·2022년 12월 3일
0

자바의 정석

목록 보기
7/12
post-thumbnail

배열이란?

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

1. 배열의 선언과 생성

1. 타입[] 변수명 - 자바서 많이씀
int[] score;
String[] name;

2. 타입 변수명[] - C언어에서 많이씀
int score[];
String name[];

배열의 생성

배열이 만들어지는 과정은

  1. 참조변수를 선언한다
  2. 배열을 생성한다
  3. 둘을 이어준다

이거당 와우~ 위의 예시에서 int[] score 요부분은 그냥 배열을 선언한 것이고, 이는 곧 참조변수를 위한 공간이 만들어진 것 뿐이다.
아직 저장공간 안만들어졌음!!

그럼 어케 저장공간은 어케 만드냐?
이전 글에서 말했듯, 기본형이 아닌 자료형들은 모두 연산자 new를 사용해서 만들어주면 된다~ 따란

int[] score;
score = new int[number];

int[] score = new int[number];

이런 식으로 만들어주게 되면 참조변수와 생성된 배열의 주소가 연결이 된다~
그럼 참조변수 score를 통해 배열을 다룰 수 있당

2. 배열의 길이와 인덱스

인덱스의 범위는 0부터 시작하므로, '배열길이 - 1' 까지

ex)
int[] score = new int[5];
이러면 score의 인덱스는 0 부터
score[0]
score[1]
score[2]
score[3]
score[4]
이렇게 0 ~ 4, int[5]가 가르키듯 저장공간 5개를 갖고 있다.

인덱스의 범위를 벗어나지 않도록 주의하자.

배열의 길이

배열의 요소의 개수, 값을 저장할 수 있는 공간의 개수. 0도 가능하대
배열은 한번 생성하면 실행 시 길이를 변경할 수 없기 때문에, 상수

엥? 그냥 거 선언된거 바꾸면 된거 아님?

중간에 늘어나게 되면, 연속적인 메모리확보에 대한 불확실성이 있기 때문에 차라리 새로운 공간을 확보하고, 기존의 내용을 복사하는 방식을 사용한다고 한다.
처음부터 길이를 잘 설정하자~!

배열의 초기화

처음 값을 잘 넣어보자~ 아 모기쉑 또왔네

int[] score = new int[]{50, 60, 70, 80};

이렇게 선언과 초기화를 동시에 하면, new int[] 대괄호 안에 길이가 알아서 들어간다 데박~

근데 이런 방식보다는

int[] score = {50, 60, 70, 80};

이렇게 new 연산자를 생략한다고 한다.!!!!
하지만 백만년에 한번씩 선언과 초기화를 따로 해야하는 경우에는

int[] score;
score = new int[]{50, 60, 70, 80, 90}; 얘는 되고

int[] score;
score = {50, 60, 70, 80}; 얘는 안된다

저렇게 new 연산자를 생략할 수 없다!!
어쨌든 새로 생성을 한 객체를 넣어줘야하기 때문일까??

3. 배열을 이용한 다양한 메서드

1. 배열의 복사

한 번 생성한 배열보다, 더 많은 저장공간이 필요한 경우

  1. for문을 이용해 새로운 배열에 하나씩 넣어주기
  2. System.arraycopy()
  3. Arrays.copyOf();

for문을 이용한 배열의 복사

int[] arr = new int[5];

int[] tmp = new int[arr.length * 2]; // arr보다 2배 길이의 tmp 배열 생성
for (int i = 0; i < arr.length; i++) {
	tmp[i] = arr[i]; // arr의 요소들을 tmp에 하나씩 넣어준다.
}
여기까지 하면 tmp 배열에 arr 배열을 넣어준거고, 남은 길이들은 0(int형 기본값)으로 채워져 있다.

arr = tmp;
요렇게 대입연산자를 이용해주면, arr도 tmp를 가리키게 되고 두 배열은
같은 배열을 가리키고 있는 중이다.

여러모로 비효율적이다 북북

System.arraycopy() 이용한 배열의 복사
지정된 범위 값을 한 번에 통째로 복사해주는 메서드다.

Arrays.copyOf() 메서드를 이용한 배열의 복사

Arrays.copyOf(어떤 배열을, 몇개나); // 처음부터 몇개를?

int[] arr = {0, 1, 2, 3, 4};
int[] arr2 = new int[arr.length];

arr2 = Arrays.copyOf(arr, 3); // arr2 = {0, 1, 2};


+)
Arrays.copyOfRange(어떤 배열을, from, to); // 중간부터 잘라먹을수 있당

arr2 = Arrays.copyOfRange(arr, 2, 3); // arr2 = {2}; idx 2 이상 3 미만
arr2 = Arrays.copyOfRange(arr, 1, 4); // arr2 = {1, 2, 3};

2.배열의 출력

println에서 char[]을 출력하는거 말고는 배열들은 for문을 돌면서 하나씩 출력해줘야됨
근데 넘 귀찮아.. -> 문자열로 변환 후 출력. 문자열은 char[]의 확장형이다~ 대박

  1. for문을 돌면서 하나씩 출력
  2. Arrays.toString()

1번은 위에서 본거를 출력으로 생각해보세여 허허

Arrays.toString()을 이용한 배열의 출력

array->String으로 변환해주는 메서드.

int[] arr = {0, 1, 2, 3, 4};
arr = Arrays.toString(arr); // arr = [0, 1, 2, 3, 4];

2차원, 다차원 배열을 출력하려면 이중 포문을 돌아야됨. 더귀찮다..
괜찮다. 갓자바는 메서드를 이거도 준비해놨다


int[][]arr2D = {{11, 12}, {21, 22}};
Arrays.deepToString(arr2D); // arr2D = [[11, 12], [21, 22]];

String 배열

Strgin배열의 선언, 생성

위에서 정수 배열 선언, 생성과 똑같다~

String[] name = new String[3];

다른 점이라면 참조형 변수 기본값은 null이기 때문에 각 요소 값이 null로 초기화된다.

String배열의 초기화

얘도 똑같음

String[] name = new String[3];
name[0] = "Kim";
name[1] = "Park";
name[2] = "Yi";

String[] name = new String[]{"Kim", "Park", "Yi"};
String[] name = {"Kim", "Park", "Yi"};

char배열과 String클래스

String클래스는 char배열에 기능(메서드)를 추가한 것이다.
차이점은, String객체(문자열)는 읽을 수만 있을 뿐, 내용을 변경할 수 없다.

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

엥? 되는데요?

그렇게 인간눈으로 봤을 때 java에 8이 붙은 것 처럼 보이지만, 여기선 str = str + "8" 작업을 수행했을 때 "java8"이라는 새로운 문자열이 저장된거다!
강도가 들어와서 죽어도 문자열을 변경하고싶다고 외쳤다면, StringBuilder클래스를 추천해주자.

String클래스의 다양한 메서드

메서드반환값설명
charAt(int idx)char문자열에서 해당 위치(idx)에 있는 문자를 반환한다.
length()int문자열의 길이 반환
substring(int form, int to)String문자열 잘라서 반환(from부터, to - 1까지), idx 하나만 적으면 그 위치부터 끝까지 잘라준다.
equals(Object obj)boolean문자열 내용이 obj와 같은지 판별
toCharArray()char[]문자열을 문자 배열로 변환 후 반환

+)

  • equals는 대, 소문자를 구분해서 비교한다. 구분 없이 비교하고싶다면 equalsIgnoreCase()를 사용해주자.
  • char[] -> String을 원한다면 String 객체에 넣어 반환하거나, Array.toString()을 사용하면된다.
char[] chArr = {'a', 'b', 'c'};
String str = new String(chArr); // char[] -> String
String str2 = Array.toString(chArr); // 근데 이건 무쓸모이지 않을까 어차피 char[] 얘 println 하면 요소 다 출력 되는디

커맨드 라인을 통해 입력받기

탈 Scanner를 해보자

C언어의 args argv를 생각하면 된다

어쩌고저쩌고 경로>java ClassName abc 123

ClassName의 클래스

public Main {
	public static void main(String[] args) {
     // 여기의 String[] args에 "abc", "123"이 들어온다고 생각하면댐
    }
}

이렇게 직접 값을 넣어주면 abc, 123이 main의 argsString 배열로 들어온다

만약 아무런 값도 입력하지 않는다면, null 대신 길이가 0인 빈 배열""이 생성되어 에러를 막아준다.

다차원 배열

쉽게 생각하면, 1차원 배열이 모이면 2차원 배열, 2차원 배열이 모이면 3차원 배열.
n차원 배열이 모이면 n+1차원 배열

어우 지저분해

int[][] score = {
					{100, 100, 100},
                    {20, 20, 20},
                    {30, 30, 30},
                    {40, 40, 40},
                    {50, 50, 50},
				};

이렇게 생긴 이차원 배열을 그림으로 표현한거다
참조변수 score는 일차원배열 score[i]를 참조하고 있고, 그 안에 또 들어가보면 이차원 배열 score[i][j]가 쭉 있다고 생각하면 된다.
그렇담 score.length는 score[i]를 참조하고 있다고 했으니 5줄이니까 5겠고, score[i]의 length는 각 3개씩 요소를 갖고 있으니 3이다 굿

그럼 요소 하나(100, 20 ...)에 접근을 하려면 score[i]에 타고 들어가서 그 안의 요소인 score[i][j]에 도달해야하는군아~ 생각할 수 있다!
더 생각해보면 모든 요소를 출력해 보려면, j 쭉 뽑고, 다음 줄 i 쭉 뽑아야하니까 이중for문을 돌아야 하는군아~ 생각하면 된다!!!

for (int i = 0; i < score.length(); i++) {
	for (int j = 0; j < score[i].length(); j++) {
    	System.out.print(score[i][j]); // 한줄을 쭉 출력
    }
    System.out.println(); // 줄바꿈
}

그럼 모든 요소를 더한 값은 간지나는 향상된 for문을 이용해 계산해보자.
얘는 저장된 값을 읽어올 수만 있다는 것에 유의하자!!

for (int i : score) {
	sum += i;
}

틀렸다. 방금 말했듯이, 배열 안의 배열로 접근해야한다!! 저렇게 쓰면 score는 이차원 배열인데, 그 안에 들어가면 일차원 배열이 쭈루룩 있을텐데.. int로 접근하면 당연히 틀린다.

for (int[] line : score) { // 이차원배열(score) 안의 일차원 배열(line)로 접근
	for (int num : line) { // 일차원 배열(line) 안의 요소 하나(num)에 접근
    	sum += num;
    }
}

요렇게 작성해야한다!!!

저렇게 정사각형, 직사각형의 다차원 배열을 많이 다루지만, 길이가 서로 다른 다차원 배열도 당연히 만들 수 있고, 접근하는건 length만 신경써주면 된다 굿

profile
어?머지?

0개의 댓글