배열이란?
하나의 블록안에 여러 데이터들을 모아 저장함으로써 데이터를 구조적으로 다루는데 도와준다.
배열의 각 구성요소를 배열 요소(element)라고 하며, 배열에서 위치를 가리키는 숫자를 인덱스(index)라고 한다.
int arr[] = new int[5];
// 0 0 0 0 0
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 1 2 3 4 5 6 7 8 9 10
배열 선언
배열은 선언시 미리 공간의 갯수(길이)를 지정해야 한다.
공간의 갯수 제한이 생긴므로 데이터를 저장하는데 있어서 제한적인 상황이 생길 수 있다.
// 일일히 하나씩 초기화
int[] arr = new int[5];
arr[0] = 1; // 인덱스로 값 초기화
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
arr[4] = 1;
// 반복문 초기화
for(int i = 0; i < score.length; i++){
arr[i] = i+1;
}
// 선언 초기화
int[] arr = {1,2,3,4,5};
배열 출력
int[] arr = {1,2,3,4,5};
System.out.println(arr); // [I@7ad041f3] -> 주솟값이 출력된다.
콘솔에 배열을 System.out.println()으로 출력하면 배열 내부가 아닌 주솟값이 출력된다.
배열을 출력하기 위해서는 for문을 사용해서 배열 각 원소들을 순회해서 출력해주거나, 자바에서 제공하는 Arrays.toString() 메소드를 사용해서 배열을 문자열 형식으로 만들어 출력해줄 수 있다.
배열 복사
공간의 제약이 있는 배열을 확장시켜주려면 어떻게 해야하는가?
공간이 큰 배열을 새로 만들고 기존의 배열의 내용을 새로 만든 배열에 복사하는 방식으로 확장시켜야 한다.
배열을 복사하는 방법은 for문으로 순회해서 직접 한 요소요소 복사하는 방식과, 자바에서 제공하는 System.arraycopy() 메서드나 Arrays.copyOf() 메서드를 사용해주면 된다.
public static void main(String[] args){
int[] arr1 = {1,2,3,4,5};
int[] arr2 = new int[arr1.length * 2];
arr2 = Arrays.copyOf(arr1, arr1.length); // arr1 배열을 arr1.length 전체 길이만큼 전체 복사
System.out.println(Arrays.toString(arr2)); // [1,2,3,4,5]
}
배열 정렬
Arrays.sort()메서드를 사용해서 배열을 정렬할 수 있다.
배열 비교
두 배열의 구성이 같은지에대한 여부를 확인하기 위해서 일일히 for문으로 순회하여 원소를 비교해도 되지만,
Arrays.equals() 메소드를 이용하면 된다.
public static void main(String[] args){
String[] arr1 = {"가", "나", "다", "라"};
String[] arr2 = {"가", "나", "다", "라"};
System.out.println("arr1 == arr2 : " + Arrays.equals(arr1,arr2));
// arr1 == arr : true
}
다차원 배열
2차원 이상의 배열을 의미하며, 배열 요소로 또 다른 배열을 가지는 배열을 의미한다.
2차원 배열 생성
int[][] score = new int[2][2];
// 선언후 데이터 삽입
score[0][0] = 1;
score[0][1] = 2;
score[1][0] = 3;
score[1][1] = 4;
// 한번에 지정해서 선언
int[][] score2 = {
{1,2},
{3,4}
}
2차원 배열 출력
중첩 for문을 사용하거나, Java에서 제공하는 Arrays.deepToString() 메서드를 통해 2차원 배열을 한방에 출력한다.
int[][] arr = {
{1,2,3},
{4,5,6},
{7,8,9}
}
System.out.println(Arrays.deepToString(arr)); // [[1,2,3],[4,5,6],[7,8,9]]
2차원 배열 비교
2차원 배열은 Arrays.deepToEquals()메소드를 사용하면 된다.
가변 배열
Java에서 다차원 배열은 마지막 차수의 길이를 다르게 지정할 수 있다.
int[][] score = {
{1,2,3,4,5},
{2,3,4},
{6,5}
}
객체 배열
배열에 정수나 문자외에 객체 자체도 배열에 넣어줄 수 있다.
객체 또한 하나의 자료형으로 취급된다.
class ObjectMake {
int id;
String descritpion;
Object(int id, String description){
this.id = id;
this.description = description;
}
ObjectMake[] arrayObjMake = new ObjectMake[5];
arrayObjMake[0] = new ObjectMake(1,"hi");
arrayObjMake[1] = new ObjectMake(2,"bye");
arrayObjMake[2] = new ObjectMake(3,"good night");
System.out.println(arrayObjMake[0].description); // "hi"
// 초기화 선언
ObjectMake[] arrayObjMake2 = {
new ObjectMake(1,"hi");
new ObjectMake(2,"bye");
new ObjectMake(3,"good night");
};
객체 배열 복사
객체로 이루어진 배열을 복사할 때 주의해야 할 점이 있다.
배열 자체는 복사가 되지만, 배열 내용물 객체는 참조 복사(주소 복사)가 된다.
배열 내용물은 여전히 같은 객체 주소를 가리키기 때문에 객체도 복사 되는 줄 알고 복사한 객체의 멤버를 변경시에 복사된 멤버에게 즉 참조하고 있는 멤버의 객체도 변경이 된다.
깊은 복사를 위해서는 for문으로 일일히 복사해주어야 한다.
class myObject{
int id;
String description;
myObject(int id, String description) {
this.id = id;
this.description = description;
}
}
myObject[] arrayObj = {
new myObject(101, "first"),
new myObject(102, "second"),
new myObject(103, "third")
};
System.out.println(Arrays.toString(arrayObj)); // [main$1myObject@251a69d7, main$1myObject@7344699f, main$1myObject@6b95977]
myObject[] arrayObj2 = new myObject[3];
for(int i = 0; i < arrayObj.length; i++) {
arrayObj2[i] = new myObject(arrayObj[i].id, arrayObj[i].description);
}
// 배열 내용물 객체의 @주소가 달라짐을 볼 수 있다.
System.out.println(Arrays.toString(arrayObj2)); // [main$1myObject@7e9e5f8a, main$1myObject@8bcc55f, main$1myObject@58644d46]
System.out.println(arrayObj[0].id); // 101
arrayObj2[0].id = 999; // 복사한 arrayObj2의 첫째 객체의 멤버를 변경
System.out.println(arrayObj2[0].id); // 999
System.out.println(arrayObj[0].id); // 101
객체 배열 정렬
객체 배열을 정렬할 때는 정렬의 기준이 필요하다.
객체 배열을 정렬하기 위해서는 Comparable 인터페이스와 Comparator 클래스를 이용한 방법을 통해 객체 배열 정렬을 할 수 있다.
Comparable
같은 타입의 인스턴스를 서로 비교해야 할때 Comparable 인터페이스를 구현해서 compareTo() 메소드를 오버라이딩 정의하고 사용한다.
import java.util.Arrays;
public class main {
public static void main(String[] args) {
// 클래스에 Comparable<> 인터페이스를 구현한다
class User implements Comparable<User> {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(User user) {
// 비교 로직을 구현
if (this.age < user.age) {
return -1;
} else if (this.age == user.age) {
return 0;
} else {
return 1;
}
}
}
User[] users = {
new User("홍길동", 32),
new User("김춘추", 64),
new User("임꺽정", 48),
new User("박혁거세", 14),
};
Arrays.sort(users); // 나이순 정렬
// Arrays.sort(users, Collections.reverseOrder()); // 역순 정렬
for (User u : users) { // 출력
System.out.println(u.name + " " + u.age + "세");
}
}
}
Comparator 클래스
Comparator 클래스도 Comparable 인터페이스와 같이 객체를 정렬하는 데 사용된다.
import java.util.Arrays;
import java.util.Comparator; // Comparator 클래스를 불러온다
public class main {
public static void main(String[] args) {
class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
User[] users = {
new User("홍길동", 32),
new User("김춘추", 64),
new User("임꺽정", 48),
new User("박혁거세", 14),
};
// Arrays.sort(배열, new Comparator<>() { ... });
Arrays.sort(users, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
return Integer.compare(u1.age, u2.age); // Integer 클래스에 정의된 compare 함수로 두 가격 정수 원시값을 비교
}
});
// java8 람다식으로 다음과 같이 축약이 가능
Arrays.sort(users, (u1, u2) -> Integer.compare(u1.age, u2.age)); // 나이순 정렬
// 출력
for (User u : users) {
System.out.println(u.name + " " + u.age + "세");
}
}
}
나이순이 아닌 이름(문자열) 순으로 정렬하려면 compareTo() 메서드를 사용하면 된다.
'Backend > 알고리즘' 카테고리의 다른 글
자료구조 - Linked List (2) | 2024.02.24 |
---|---|
자료구조 - HashMap (1) | 2024.02.24 |
[백준] 2343번 - 기타레슨 (1) | 2023.12.08 |
[백준] 2729번 - 보석상자 (0) | 2023.12.08 |
이분탐색 (1) | 2023.12.07 |