컬렉션
==> 배열의 부족한 점 보완.
: 자바 자료구조를 미리 구현해서 제공하는 API
1-1. List
- 값만 저장, 순서 있음.
(Vector, ArrayList, LinkedList...)
1-1-1. ArrayList
: 배열 대응
- 생성, 타입, 크기 제약 없다.
--- 단, 무작위로 담으면 관리가 어려움. => <타입> : 제너릭, 타입 한정자 ==> 담을 타입을 한정하여 담음.
ArrayList<한정할 타입> 리스트 명 = new ArrayList<>(); // ArrayList 생성
.add("aaa"); // 마지막 데이터로 추가
.add(0, "bbb"); // 지정한 인덱스(0)에 데이터("bbb") 끼워넣기. (한 칸 씩 미루고!)
.get(방번호) // 리스트의 해당 방의 데이터 출력
.size() // == .length / 데이터 몇개나 들어갔는지 알 수 있음.
.set(0, "111"); // 지정한 인덱스(0)의 값을 지우고 데이터("111") 추가하기.
.contains("sss") // 값("sss")이 있으면 true, 없으면 false 반환.
.indexOf("sss") // 값("sss")의 위치를 찾아줌.(몇번 방에 있다~) 없으면 -1 반환.
.remove(방번호) // 해당 방 번호의 데이터 삭제
.remove(값) // 해당 값 찾아서 삭제
.isEmpty() // 리스트가 비었는지 확인. 비었으면 true, 아니면 false 반환.
.clear() // 리스트 데이터 전체 삭제
▼ ArrayList equals / indexOf 예
- String 클래스는 equals 가 재정의 되어 있어서 indexOf 같은 API를 쓸 수 있지만
나머지는 거의 equals가 재정의되어 있지 않음. => 그래서 따로 재정의 해줘야 함! (Override)
더보기
package arraylist;
import java.util.ArrayList;
import java.util.Scanner;
public class ArrayListTest1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
ArrayList<String> list2 = new ArrayList<>();
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("문자열 입력. 멈추려면 /stop 입력");
String txt = sc.next();
if (txt.startsWith("/stop")) { // "/stop으로 시작하는 문자"를 입력하면.
break;
}
list2.add(txt);
}
// list2 전체 데이터 출력
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
// 검색. equals로 비교
// 검색할 단어 입력 받음.
// if(단어.equals(list2.get(i)))
System.out.println("검색할 단어: ");
String txt = sc.next();
int i;
for (i = 0; i < list2.size(); i++) {
if (txt.equals(list2.get(i))) {
System.out.println(i + "번 방에 있습니다.");
break;
}
}
// for문은 i가 list2.size()가 될 때 루프가 끝나니까@
if (i == list2.size()) {
System.out.println("없습니다.");
}
// 객체의 equals()가 재정의되어있다면, indexOf()로 검색 가능.
// indexOf() -- 객체의 equals()메서드로 동알한 객체를 찾아서 위치 반환.
int idx = list2.indexOf(txt);
if(idx < 0) {
System.out.println("없습니다.");
} else {
System.out.println(idx + "번 방에 있습니다.");
}
}
}
▼ ArrayList API 다양한 예
더보기
package langTest;
import java.util.ArrayList;
public class ArrayList2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// arraylist 생성. 타입, 크기 제약 없다. -- 단, 무작위로 담으면 관리가 어려움.
//<타입>: 제너릭. 타입한정자.
ArrayList<String> list = new ArrayList();
//add(); 끝에 데이터 추가
list.add("aaa"); // 마지막 데이터로 추가
list.add(0, "bbb"); //지정한 인덱스에 데이터 끼워넣기 (한칸씩 미루고)
list.add("ccc");
list.add("ddd");
list.set(2, "abcd"); // 인덱스 위치의 값을 지우고 추가
int i = 0;
System.out.println("전체 데이터");
for (i = 0; i < list.size(); i++) { // list.size(): 데이터 개수
System.out.println(list.get(i)); // get(i): i번째 방의 값 반환
}
System.out.println("ddd 찾고 삭제");
if (list.contains("ddd")) { //contains(): 값이 있으면 true,없으면 false 반환
int idx = list.indexOf("ddd"); // indexOf(): 값의 위치를 찾아줌. 없으면 -1반환.
System.out.println("ddd는" + idx + "방에 있음");
list.remove(idx); //remove(방번호): 방번호 데이터 한 개 삭제.
}
System.out.println("aaa 삭제");
list.remove("aaa"); //remove(삭제할데이터): 데이터 찾아서 삭제.
System.out.println("삭제 후 전체 데이터");
for (i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//비었나 확인
if(list.isEmpty()) { //isEmpty(): 리스트 비었으면 true. 아니면 false 반환.
System.out.println("비었음");
} else {
System.out.println("데이터 있음");
}
System.out.println("데이터 전체 삭제");
list.clear(); //clear(): 리스트 데이터 전체 삭제.
if(list.isEmpty()) {
System.out.println("비었음");
} else {
System.out.println("데이터 있음");
}
}
}
===================================
전체 데이터
bbb
aaa
abcd
ddd
ddd 찾고 삭제
ddd는3방에 있음
aaa 삭제
삭제 후 전체 데이터
bbb
abcd
데이터 있음
데이터 전체 삭제
비었음
▼ 배열 vs ArrayList 구현 비교
1) 배열 ver.
더보기
package product;
import java.util.Scanner;
public class ProductsService {
private Products[] prods = new Products[30];
private int cnt; // 제품 개수 카운트 변수
public ProductsService(int size) {
prods = new Products[size]; // size 만큼 방을 만든다.
}
// 새 상품 등록
public void addProduct(Scanner sc) {
if (cnt >= prods.length) { // cnt: 제품수, prods.length: 방의 개수
System.out.println("배열이 다 찼습니다.");
return; // 추가 취소.
}
int idx = 0;
Products p = new Products();
while (idx >= 0) {
System.out.println("num: ");
p.setNum(sc.nextInt());
idx = getByNum(p.getNum()); // 중복:0이상의 값. 중복안됨:-1
}
System.out.println("name: ");
p.setName(sc.next());
System.out.println("route: ");
p.setRoute(sc.next());
System.out.println("sellerId: ");
p.setSellerid(sc.next());
System.out.println("price: ");
p.setPrice(sc.nextInt());
System.out.println("amount: ");
p.setAmount(sc.nextInt());
prods[cnt++] = p; // 배열에 넣은 다음 cnt 1 증가.
}
// 번호 검색 메서드
public int getByNum(Scanner sc) {
System.out.println("검색/수정/삭제할 제품 방 번호:");
int num = sc.nextInt();
// 배열에서 요소를 하나씩 꺼내서 제품번호와 num을 비교해 같은 것 찾음.
for (int i = 0; i < cnt; i++) {
if (prods[i].getNum() == num) {
return i;
}
}
return -1; // 못찾으면 루프 밖으로 나오게 됨.
}
// 파라메터로 검색할 번호 받아서 방 번호 리턴.
public int getByNum(int num) {
for (int i = 0; i < cnt; i++) {
if (prods[i].getNum() == num) {
return i;
}
}
return -1;
}
// 검색해서 출력하는 메서드
public void printProduct(Scanner sc) {
int idx = getByNum(sc);
if (idx < 0) {
System.out.println("없다");
} else {
System.out.println(prods[idx]);
}
}
public void editProduct(Scanner sc) {
System.out.println("수정할 제품 방 번호:");
int idx = getByNum(sc);
if (idx < 0) {
System.out.println("없다");
} else {
System.out.println("수정 전 데이터");
System.out.println(prods[idx]);
boolean flag = true;
while (flag) {
System.out.println("수정할 제품 정보\n1.num 2.name 3.route 4.sellerId 5.price 6.amount 7.종료");
int x = sc.nextInt();
switch (x) {
case 1:
System.out.println("new num: ");
prods[idx].setNum(sc.nextInt());
System.out.println(prods[idx]);
break;
case 2:
System.out.println("new name: ");
prods[idx].setName(sc.next());
System.out.println(prods[idx]);
break;
case 3:
System.out.println("new route: ");
prods[idx].setRoute(sc.next());
System.out.println(prods[idx]);
break;
case 4:
System.out.println("new sellerId: ");
prods[idx].setSellerid(sc.next());
System.out.println(prods[idx]);
break;
case 5:
System.out.println("new price: ");
prods[idx].setPrice(sc.nextInt());
System.out.println(prods[idx]);
break;
case 6:
System.out.println("new amount: ");
prods[idx].setAmount(sc.nextInt());
System.out.println(prods[idx]);
break;
case 7:
System.out.println("수정 종료");
flag = false;
break;
}
}
}
}
// 삭제 메소드
public void deleteProduct(Scanner sc) {
System.out.println("삭제할 제품 방 번호:");
int idx = getByNum(sc);
if (idx < 0) {
System.out.println("없다");
} else {
System.out.println(idx + "번째 방의 제품 정보를 삭제합니다");
for (int i = idx; i < cnt - 1; i++) {
prods[i] = prods[i + 1];
}
cnt--; // 다음에 데이터가 추가되면 마지막 방에 덮어씌워짐.
}
}
public void printAll() {
for (int i = 0; i < cnt; i++) {
System.out.println(prods[i]);
}
}
}
2) ArrayList ver.
2-1) equals 재정의되지 않은 버전
더보기
package product1;
import java.util.ArrayList;
import java.util.Scanner;
public class Product2Service {
//Product 여러개 담기 위해 ArrayList 생성
private ArrayList<Product2> list;
public Product2Service() {
list = new ArrayList<>();
}
// 제품 추가
public void addProduct(Scanner sc) {
Product2 p = new Product2();
int idx = 0; // while문 조건에 만족할 값으로 초기화
while (idx >= 0) { //num 중복 체크
System.out.println("num: ");
p.setNum(sc.nextInt());
idx = getByNum(p.getNum()); //제품 번호로 검색 -> 중복이면 -1 -> while종료
}
System.out.println("name: ");
p.setName(sc.next());
System.out.println("route: ");
p.setRoute(sc.next());
System.out.println("sellerId: ");
p.setSellerid(sc.next());
System.out.println("price: ");
p.setPrice(sc.nextInt());
System.out.println("amount: ");
p.setAmount(sc.nextInt());
list.add(p); // ArrayList 추가
}
//파라메터로 번호 받아서 검색하여 방번호 반환, 못찾으면 -1.
public int getByNum(int num) {
int i;
for (i = 0; i < list.size(); i++) { // 제품 수 만큼 반복
Product2 p = list.get(i); // i번째 방의 Product 객체 꺼내서 변수 p에 담음
if (num == p.getNum()) { // 검색 num과 제품 번호 비교해서 같으면 방번호 리턴.
return i;
}
}
return -1;
}
// 제품 번호로 검색하여 출력
public void getProduct(Scanner sc) {
System.out.println("검색할 제품 번호: ");
int num = sc.nextInt();
int idx = getByNum(num);
if (idx < 0) {
System.out.println("없다.");
} else {
Product2 p = list.get(idx);
System.out.println(p);
}
}
// 제품명 검색
// 제품명은 중복가능. 여러개 검색할 수 있다.
public ArrayList<Product2> getByName(Scanner sc) {
System.out.println("검색할 제품명: ");
String name = sc.next();
ArrayList<Product2> data = new ArrayList<>(); // 이름으로 검색된 객체들을 담을 리스트
for (int i = 0; i < list.size(); i++) {
Product2 p = list.get(i);
if (name.equals(p.getName())) {
data.add(p);
}
}
return data;
}
// 이름으로 검색한 결과 출력.
public void printByName(Scanner sc) {
ArrayList<Product2> data = getByName(sc);
if (data.isEmpty()) {
System.out.println("검색된 제품 없음");
return;
}
for (int i = 0; i < data.size(); i++) {
Product2 p = data.get(i);
System.out.println(p);
}
}
// 수정
public void editProduct(Scanner sc) {
System.out.println("수정할 제품 번호: ");
int num = sc.nextInt();
int idx = getByNum(num);
if (idx < 0) {
System.out.println("없다.");
} else {
Product2 p = list.get(idx); // idx 방의 객체를 꺼내서 변수 p에 저장
System.out.println("new name");
p.setName(sc.next());
System.out.println("new price");
p.setPrice(sc.nextInt());
System.out.println("new amount");
p.setAmount(sc.nextInt());
}
}
// 삭제
public void deleteProduct(Scanner sc) {
System.out.println("수정할 제품 번호: ");
int num = sc.nextInt();
int idx = getByNum(num);
if (idx < 0) {
System.out.println("없다.");
} else {
list.remove(idx);
// remove(방번호): 그 방에 있는 값 삭제.
// remove(객체): 삭제할 값을 찾아서 삭제.
}
}
public void getAll() {
for (int i = 0; i < list.size(); i++) {
Product2 p = list.get(i);
System.out.println(p);
}
}
}
2-2) equals 재정의된 버전
더보기
VO
// this와 obj 비교
@Override
public boolean equals(Object obj) { //업캐스팅됨
// TODO Auto-generated method stub
//instanceof: 타입 비교 연산자. 타입 같으면 true, 다르면 false 반환
if (obj instanceof Product2) {
Product2 p = (Product2)obj;
if (p.num == this.num) { //제품번호만 같으면 같은 객체로 처리
return true;
}
}
return false;
}
SERVICE
package product2;
import java.util.ArrayList;
import java.util.Scanner;
public class Product2Service {
// Product 여러개 담기 위해 ArrayList 생성
private ArrayList<Product2> list;
public Product2Service() {
list = new ArrayList<>();
}
// 제품 추가
public void addProduct(Scanner sc) {
Product2 p = new Product2();
int idx = 0; // while문 조건에 만족할 값으로 초기화
while (idx >= 0) { // num 중복 체크
System.out.println("num: ");
p.setNum(sc.nextInt());
// 객체의 equals()가 재정의되어있다면, indexOf()로 검색 가능.
// indexOf() -- 객체의 equals()메서드, 동일한 객체를 찾아서 위치 반환.
idx = list.indexOf(p);
}
System.out.println("name: ");
p.setName(sc.next());
System.out.println("route: ");
p.setRoute(sc.next());
System.out.println("sellerId: ");
p.setSellerid(sc.next());
System.out.println("price: ");
p.setPrice(sc.nextInt());
System.out.println("amount: ");
p.setAmount(sc.nextInt());
list.add(p); // ArrayList 추가
}
// 제품 번호로 검색하여 출력
public void getProduct(Scanner sc) {
System.out.println("검색할 제품 번호: ");
int num = sc.nextInt();
// 검색할 번호를 Product2 객체에 담는다.
// 이 코드는 equals()를 사용해서 객체를 비교하기 때문이다.
// equals(): 객체끼리 비교함. 그래서 Product2 객체 p에 검색할 번호만 저장->
// arraylist에서 Product2 객체를 하나씩 꺼내 p와 equal()로 비교.
// p.equals(list.get(i)) <<- 자동으로 처리해줌.
Product2 p = new Product2();
p.setNum(num);
int idx = list.indexOf(p); // indexOf가 true가 되는 값을 반환해서 idx에 담음.
if (idx < 0) { // 반환값이 없으면 없는 거임.
System.out.println("없다.");
} else {
System.out.println(list.get(idx));
}
}
// 제품명 검색
// 제품명은 중복가능. 여러개 검색할 수 있다.
public ArrayList<Product2> getByName(Scanner sc) {
System.out.println("검색할 제품명: ");
String name = sc.next();
ArrayList<Product2> data = new ArrayList<>(); // 이름으로 검색된 객체들을 담을 리스트
for (int i = 0; i < list.size(); i++) {
Product2 p = list.get(i);
if (name.equals(p.getName())) {
data.add(p);
}
}
return data;
}
// 이름으로 검색한 결과 출력.
public void printByName(Scanner sc) {
ArrayList<Product2> data = getByName(sc);
if (data.isEmpty()) {
System.out.println("검색된 제품 없음");
return;
}
for (int i = 0; i < data.size(); i++) {
Product2 p = data.get(i);
System.out.println(p);
}
}
// 수정
public void editProduct(Scanner sc) {
System.out.println("수정할 제품 번호: ");
int num = sc.nextInt();
Product2 p = new Product2();
p.setNum(num);
int idx = list.indexOf(p);
if (idx < 0) {
System.out.println("없다.");
} else {
Product2 p2 = list.get(idx); // idx 방의 객체를 꺼내서 변수 p2에 저장
System.out.println("new name");
p.setName(sc.next());
System.out.println("new price");
p.setPrice(sc.nextInt());
System.out.println("new amount");
p.setAmount(sc.nextInt());
}
}
// 삭제
public void deleteProduct(Scanner sc) {
System.out.println("삭제할 제품 번호: ");
int num = sc.nextInt();
Product2 p = new Product2();
p.setNum(num);
//remove(객체): 파라메터와 동일한 객체를 equals()로 찾아서 삭제.
//정상삭제되면 true, 아니면 false 반환.
if(list.remove(p)) {
System.out.println("제품이 삭제되었습니다.");
} else {
System.out.println("없는 제품입니다. 삭제가 취소되었습니다.");
}
}
public void getAll() {
for (int i = 0; i < list.size(); i++) {
Product2 p = list.get(i);
System.out.println(p);
}
}
}
1-1-2. 반복자
- 배열, 리스트는 다음 칸으로 이동 요소를 하나씩 추출하는 동작을 반복함 -> 이 작업을 자동 처리해줌.
- 꼭 사용할 필요는 없다 ㅎㅎ
* 외부에서 사용
Iterator<요소타입> 반복자명 = 리스트명.iterator(); // 생성
while (iter.hasNext()) { // 다음에 읽을 요소 있으면 true, 아니면 false 반환.
요소타입 변수명 = iter.next(); // 다음 요소 추출
}
* 내부에서 사용 (요즘 주로 사용)
for(요소타입 변수명 : 리스트명) { // 데이터 개수 만큼 루프 돎.
변수로 원하는 작업
}
for(EmpVo vo:list) {
System.out.println(vo);
}
예시
더보기
package arraylist;
import java.util.ArrayList;
import java.util.Iterator;
public class 반복자 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
// 반복자를 외부에서 사용
Iterator<String> iter = list.iterator();
while (iter.hasNext()) { // 다음칸에 요소 있는지, 없을때까지 도는 루프.
String s = iter.next(); // 요소 추출
System.out.println(s);
}
// 반복자를 내부 사용.
for (String s : list) { //for(요소타입 변수명 : 리스트명) { 변수로 원하는 작업 }
System.out.println(s);
}
}
}
1-2. Map
- 키와 값을 쌍으로 저장 => 빠른 검색 지원
- 키: 검색의 기준. 중복 허용 안 함.
- 값: 넣고 싶은 내용. 순서 없음 ---> 출력할 때 넣은 순서대로 출력되지 X
- Hashmap()이 가장 많이 쓰임.
HashMap<키 타입, 값 타입> 맵 이름 = new HashMap<>(); // 맵 생성
맵 이름.put(키, 값); // 추가
맵 이름.get(키); // 검색
맵 이름.keySet(); // 키 묶음
맵 이름.values(); // 값 묶음
// 맵 생성. 키 타입은 int, 값 타입은 String
// 키 값은 찾는 기준이므로 중복 허용 안됨.
HashMap<Integer, String> map = new HashMap<>();
// map.put(키, 값): 맵에 데이터 추가
map.put(1, "aaa");
map.put(2, "bbb");
map.put(3, "ccc");
System.out.println(map.get(1));
System.out.println(map.get(2));
System.out.println(map.get(3));
HashMap<String, String> map2 = new HashMap<>();
// map.put(키, 값): 맵에 데이터 추가
map2.put("name", "aaa");
map2.put("tel", "1234");
map2.put("address", "seoul");
System.out.println("name: " + map2.get("name"));
System.out.println("tel: " + map2.get("tel"));
System.out.println("address: " + map2.get("address"));
▼ 반복자 써서 map 키 & 값 출력
// map2의 키 묶음에 반복자를 붙여서 반환
// keySet(): 키 묶음
for(String key : map2.keySet()) {
System.out.print(key + ": ");
System.out.println(map2.get(key)); // 키로 값 추출
}
// values(): 값 묶음
for(String value : map2.values()) {
System.out.println(value);
}
============================
address: seoul
name: aaa
tel: 1234
seoul
aaa
1234