지금까지 여러 데이터를 묶어서 다룰 때 배열을 사용했습니다. 그런데 실제 프로그램을 만들다 보면 배열이 불편한 순간이 옵니다.
// 배열로 채팅 접속자 관리
String[] users = new String[100]; // 최대 100명? 101명 오면?
int count = 0;
// 접속
users[count] = "철수";
count++;
// "철수" 퇴장 - 복잡!
for (int i = 0; i < count - 1; i++) {
users[i] = users[i + 1]; // 뒤에서 앞으로 밀기
}
users[count - 1] = null;
count--;
문제가 보이시나요?
1. 크기 고정 : 처음에 100으로 잡으면 101번째는 못 들어옴
2. 삭제 복잡 : 중간 삭제 후 뒤 요소를 직접 밀어야 함
3. count 관리 : 실제 개수를 변수로 따로 관리해야 함
ArrayList 는 이 세 가지 불편함을 모두 해결한 클래스입니다.
import java.util.ArrayList;
ArrayList<String> users = new ArrayList<>(); // 크기 미리 안 정해도 됨
users.add("철수"); // 추가
users.add("영희");
users.remove("철수"); // 삭제 - 한 줄 끝!
System.out.println(users.size()); // 실제 개수 자동 관리
ArrayList 를 선언할 때 꺽쇠 안에 저장할 타입을 씁니다.
ArrayList<String> names = new ArrayList<>(); // 문자열만
ArrayList<Integer> scores = new ArrayList<>(); // 정수만
왜 정수를 넣을때 int를 못 넣냐면 int는 기본타입이기 때문이다
객체를 넣어야 한다.
string과 integer는 참조형 객체이다
타입을 지정하면 잘못된 타입을 넣을 때 실행 전에 오류를 잡아줍니다.
ArrayList<String> list = new ArrayList<>();
list.add("철수");
list.add(100); // 컴파일 오류! String 만 가능
문법 연습
package io.ch17_1.array;
import java.util.ArrayList;
public class ArrayListEx3 {
public static void main(String[] args) {
// 1. 정수를 담은 리스트
ArrayList<Integer> intList = new ArrayList<>();
intList.add(10);
intList.add(20);
intList.add(30);
System.out.println("정수 리스트 : " + intList);
// 2. 실수를 담은 리스트
ArrayList<Double> doubleList = new ArrayList<Double>();
doubleList.add(1.0);
doubleList.add(2.0);
doubleList.add(3.0);
System.out.println(doubleList);
// 3. 불리언 담을 리스트
ArrayList<Boolean> booleanList = new ArrayList<>();
booleanList.add(true);
booleanList.add(false);
// 사용자 정의 객체를 담는 리스트
ArrayList<Book2> book2List = new ArrayList<>();
book2List.add(new Book2("자바책"));
book2List.add(new Book2("RDBMS책"));
// book2List.get(0) ==> 주소값.title
System.out.println(book2List.get(0).title);
System.out.println(book2List.get(1).title);
try {
System.out.println(book2List.get(2).title);
} catch (Exception e) {
e.printStackTrace(); // sout
}
System.out.println("프로그램 정상 종료");
} // end of main
} // end of class
class Book2 {
String title;
public Book2(String title) {
this.title = title;
}
@Override
public String toString() {
return "[title=" + title + "]";
}
}
book타입을 추가할때는 객체가 생성되기 전이므로 객체를 만들면서 add를 하는 모습이다.
intList.add(10); 이거는 intList.add(Integer.valueOf(10)); 이렇게 자동으로 값을 객체로 바꿔준다.
10을 integer 객체로 바꿔주는 메서드이다.
get()은 그 리스트에 저장된 타입 그대로 돌려준다.
import java.util.ArrayList;
class Member {
int id;
String name;
Member(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Member{id=" + id + ", name='" + name + "'}";
}
}
public class Main {
public static void main(String[] args) {
ArrayList<Member> list = new ArrayList<>();
list.add(new Member(1, "김철수"));
list.add(new Member(2, "이영희"));
System.out.println(list);
Member m1 = list.get(0);
Member m2 = list.get(1);
System.out.println(m1);
System.out.println(m2);
}
}
ArrayList는 Member 객체를 저장하는 리스트이다.
get(index)는 리스트 자체를 반환하는 것이 아니라, 해당 인덱스에 저장된 요소 하나를 반환한다.
따라서 list.get(0)의 반환 타입은 Member이다.
원래 객체를 출력하면 기본 toString()이 호출되어 주소 형태의 문자열이 나올 수 있지만, Member 클래스에서 toString()을 오버라이딩했기 때문에 객체의 id와 name 정보가 문자열로 출력된다.
for (Member member : list) {
System.out.println(member);
}
이것도 밑에꺼랑 같은말이다.
for (int i = 0; i < list.size(); i++) {
Member member = list.get(i);
System.out.println(member);
}
이 코드도 list 안의 Member 요소를 하나씩 가져와서 member 변수에 담아 출력하는 것이다.