▶ 컬렉션
1) 정의
- 자바에서 제공하는 자료구조를 담당하는 프레임워크
- 추가, 삭제, 정렬 등의 기능을 간단히 해결해줌
- java.util 패키지에 포함됨
2) 배열과 컬렉션의 비교
배열 | 컬렉션 |
한 번 크기를 지정하면 변경 불가 | 크기의 제약이 없음 |
추가, 삭제, 정렬 어려움 | 추가, 삭제, 정렬 쉬움 |
한 타입의 데이터만 저장 가능 | 여러 타입의 데이터 저장 가능 |
3) 종류
- List
- Set
- Map
▶ List
1) 정의
- 자료들을 순차적으로 나열한 자료구조
- 객체배열과 유사
2) 특징
- 순서가 유지, 저장됨
- 인덱스로 관리
- 객체의 중복 저장 가능
3) List의 후손
ArrayList | 초기 저장 용량은 10으로 설정 |
용량을 초과한 객체가 들어오면 길이가 자동으로 변화, 고정도 가능 | |
검색, 조회에 효율적 | |
동기화를 제공하지 않음 | |
LinkedList | 인접 참조를 링크해 체인처럼 관리 |
추가, 수정, 삭제에 효율적 | |
Vector | ArrayList와 동일하나 동기화를 제공, 성능이 떨어지는 편 |
4) Array List
- 작성법
List [변수명] = new ArrayList();
// 기본 생성자 사용시 길이 10짜리의 리스트가 생성됨
// 저장 타입을 제한하고 싶은 경우 *제네릭(Generics) 를 사용해 작성함
List< 타입 > [변수명] = new ArrayList< 타입 >();
- 주로 사용되는 메서드
1. List.add(Object e) : 리스트에 객체를 추가
* Object를 매개변수로 사용시 모든 객체를 매개변수로 전달할 수 있음
/**
* 1. 학생 정보 추가 메서드
* - 추가 성공시 "성공" , 실패시 "실패" 문자열 반환
*/
public String addStudent() throws InputMismatchException {
System.out.println("========== 학생 정보 추가 ==========");
System.out.print("이름 : ");
String name = sc.next();
System.out.print("나이 : ");
int age = sc.nextInt(); // InputMismatchException
sc.nextLine(); // 입력 버퍼에 남은 개행문자 제거
System.out.print("사는곳 : ");
String region = sc.nextLine();
System.out.print("성별 : ");
char gender = sc.next().charAt(0); //String -> char
System.out.print("점수 : ");
int score = sc.nextInt(); // InputMismatchException
// Student 객체 생성해 List에 추가
if(studentList.add(new Student(name, age, region, gender, score))) {
// List.add(Student e)
// -> 제네릭 <Student>때문에 리스트 타입이 제한됨
// (반환형)
// add()는 boolean타입을 반환하는 메서드로,
// 무조건 true를 반환 == 무조건 "성공"을 반환!
// 대신 예외가 발생해서 add() 수행 전 메서드가 종료될 수는 있으므로
// throws InputMismatchException 를 이용해 예외처리를 할 것 !!!!
return "성공";
}else {
return "실패";
}
}
2. List.size() : 리스트의 길이를 확인
3. Object List.get(index i) : 리스트에서 i번째 인덱스에 있는 객체를 반환
/** 2. 학생 전체 조회 메서드 */
public void selectAll() {
System.out.println("========== 학생 전체 조회 =========");
// * studentList가 비었는지 확인하는 방법
// 1) studentList.size()==0 -> List의 개수 확인
// 2) studentList.isEmpty() -> (boolean) 비어있으면 true출력
if(studentList.size()==0) {
System.out.println("학생 정보가 없습니다.");
return;
// 현재 메서드를 종료하고, 호출한 곳으로 돌아감
// 반환값이 없어도 됨 (void)
}
----------------------------------------------------------------
// * List의 인덱스를 이용해 저장된 개수를 얻어오기 [1]
// for문 사용
// List.size()를 이용해 저장된 개수 확인 (배열명.length 대신 사용)
for(int i = 0 ; i <studentList.size() ; i++) {
System.out.println(studentList.get(i));
//studentList에서 i번째 인덱스요소를 얻어와 출력
}
----------------------------------------------------------------
// * List의 인덱스를 이용해 저장된 개수를 얻어오기 [2]
// 향상된 for문 (for each문) 사용
// - 컬렉션, 배열의 모든 요소를 순차적으로 반복 접근할 수 있는 for문
// - 0번 인덱스부터, 마지막 요소까지 인덱스를 1씩 증가한다
// [작성법]
// for( 컬렉션 또는 배열에서 꺼낸 한 개의 요소 저장할 변수 : 컬렉션명 혹은 배열명){}
int index = 0;
for( Student std : studentList){
// std에for문 반복시마다 0,1,2,... 인덱스 요소들이 한번씩 저장됨
System.out.print( (index++) + "번 : ");
System.out.println( std );
}
}
4. Object List.remove(int index) : List에서 index번째 요소를 제거
이 때, 제거된 요소가 반환되고
중간에 비어있는 index가 없게 하기 위해 동작시 뒤쪽 요소를 한칸씩 당겨온다
/**
* 4. 학생 정보 제거 메서드
*/
public String removeStudent() throws InputMismatchException {
System.out.println("========== 학생 정보 삭제 ==========");
System.out.print("인덱스 번호 입력 : ");
int index = sc.nextInt();
sc.nextLine();
// 1) 학생 정보가 studentList에 있는가 ?
if(studentList.isEmpty()) {
return "입력된 학생 정보가 없습니다.";
// 2) 입력된 숫자가 0보다 큰가? (음수 검사)
}else if(index<0) {
return "음수는 입력할 수 없습니다.";
// 3) 만약 문자열을 입력한 경우 -> throws 예외처리
// 4) 입력받은 숫자가 studentList범위 내 인덱스 번호인가?
}else if(index >= studentList.size()){
return "범위를 넘어선 값을 입력할 수 없습니다.";
// 5) 삭제 코드 작성
}else {
System.out.println("정말 삭제 하시겠습니까 ? (Y/N) ");
char ch = sc.next().toUpperCase().charAt(0);
// String -> 대문자 String -> 대문자 0번 인덱스 문자로 변환
// * String.toUpperCase(); : 문자열을 대문자로 변경
if(ch == 'Y') {
Student temp = studentList.remove(index);
return temp.getName() + "의 정보가 제거되었습니다. ";
}else {
return "취소";
}
}
}
▶ Set
1) 정의
- 저장 순서가 유지되지 않고, 중복 객체도 저장하지 못하게 하는 자료구조
2) 특징
- 순서 없음
- 중복저장 안됨 (null도 중복안됨)
3) Set의 후손
HastSet | Set의 대표적인 자식 클래스 |
저장되는 객체의 equals(), hashCode() 오버라이딩 필수 | |
LinkedHashSet | 순서 유지 Set |
TreeSet | 자동 정렬 Set |
* Hash라는 단어가 붙은 모든 컬렉션은 반드시 저장되는 객체에
equals(). hasgCode() 메서드를 오버라이딩해야한다.
4) HastSet
- 작성법
Set< 저장할 타입 > set = new HashSet< 저장할 타입 >();
----------------------------------------------------
// equals() hashCode() 오버라이딩 자동완성 alt + shift + s
@Override
public int hashCode() {
return Objects.hash(age, id, pw);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Member other = (Member) obj;
return age == other.age && Objects.equals(id, other.id) && Objects.equals(pw, other.pw);
}
- 주로 사용되는 메서드
1. Set.add( 저장할 타입 ) : Set에 객체를 추가
Set<String> set = new HashSet<String>();
// Set.add(String e)
set.add("네이버");
set.add("카카오");
set.add("라인");
set.add("쿠팡");
set.add("배달의민족");
set.add("배달의민족");
set.add("배달의민족");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
// 출력시 [null, 배달의민족, 카카오, 네이버, 쿠팡, 라인] 출력됨
// 순서x, 중복x, null 중복 x 확인 가능
2. Set.size() : Set에 저장된 데이터의 개수 반환
3. Set.remove(저장할 타입) : Set에 저장된 객체 중 매개변수와 필드값이 같은 객체를 제거
만약 Hash라는 단어가 포함된 Set면 hashCode()도 동일해야 삭제가능
지우면 true반환, 못지우면 false를 반환함
Set<String> set = new HashSet<String>();
set.add("네이버");
set.add("카카오");
set.add("라인");
set.add("쿠팡");
set.add("배달의민족");
set.add("배달의민족");
set.add("배달의민족");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
// [null, 배달의민족, 카카오, 네이버, 쿠팡, 라인] 출력됨
System.out.println("저장된 데이터의 수 : "+set.size());
// 6 출력
System.out.println(set.remove("라인")); // 지웠으면 true 반환
System.out.println(set.remove("야놀자")); // 못지웠으면 false 반환
System.out.println(set);
// 출력시 remove된 내역 확인 [null, 배달의민족, 카카오, 네이버, 쿠팡]
4. set.iterator() : 컬렉션에서 제공하는 컬렉션 객체 반복 접근자
(컬렉션에 저장된 데이터를 임의로 하나씩 반복적으로 꺼내는 역할)
5. it.hasNext() : 다음값이 있으면 true 반환
it.next() : 다음 값(객체)를 얻어옴
Set<String> set = new HashSet<String>();
set.add("네이버");
set.add("카카오");
set.add("쿠팡");
set.add("배달의민족");
set.add(null);
Iterator<String> it = set.iterator();
while(it.hasNext()) {
// it.hasNext() : 다음값이 있으면 true 반환
// it.next() : 다음 값(객체)를 얻어옴
// 하나씩 꺼냈을 때 다음값이 없는 경우 == false 반복 종료
String temp = it.next();
System.out.print(temp + ",");
}
// null, 배달의민족, 카카오, 네이버, 쿠팡 출력함
-----------------------------------------------
// 향상된 for문을 사용해 간단히 출력할 수도 있다
for( String temp : set ) {
System.out.println(temp);
}
6. equals() : 원래는 문자열의 값이 같은지 비교하는 메서드인데,
현재 객체와 매개변수로 전달받은 객체의 필드가 같은지 비교하는 형태로 오버라이딩해야함.
hashCode() : 중복제거를 위해 객체의 필드값을 이용해 특정 정수를 반환해주는 메서드,
필드 값이 같은 객체는 같은 정수를 반환할 수 있도록함.
// 중복 제거를 위해!!!!
// set 사용시 equals() 오버라이딩 필수!
// hash- 사용시 hashCode() 오버라이딩 필수!
public void ex3() {
// equals()만 오버라이딩 된 Member를 set에 저장
// [key point] 중복 제거가 되는가?
Set<Member> memberSet = new HashSet<Member>();
memberSet.add( new Member("user01", "pass01", 30));
memberSet.add( new Member("user02", "pass02", 40));
memberSet.add( new Member("user03", "pass03", 20));
memberSet.add( new Member("user04", "pass04", 25));
memberSet.add( new Member("user04", "pass04", 25));
for(Member mem : memberSet) {
System.out.println(mem); // 중복제거 되지 않음
}
// - equals()가 오버라이딩 되어있지만 중복 제거가 되지 않음
// - 중복 제거를 위해 hashSet은 hashCode()도 오버라이딩 해야한다
// hashCode() 오버라이딩 후
Member mem1 = new Member("user01", "pass01", 30);
Member mem2 = new Member("user01", "pass01", 30);
Member mem3 = new Member("user01", "pass01", 31);
System.out.println(mem1.hashCode());
System.out.println(mem2.hashCode());
System.out.println(mem3.hashCode());
// 필드값이 동일하기때문에, mem1과 mem2는 같은 해쉬코드 출력
// mem3은 다른 해쉬코드를 출력한다.
// hashCode() 오버라이딩 후 위에서 실행했던,
// for문을 재실행해보면 중복이 제거된 내역을 확인 할 수 있다.
}
7. Wrapper 클래스 : 기본 자료형을 객체로 포장하는 클래스
컬렉션에 기본 자료형 값을 저장할 때 사용,
기본 자료형에 없던 추가 기능 혹은 값을 이용하고 싶을 때 사용함
(Wrapper 클래스 종류 : Integer, double, Boolean, Byte, Short, Long, Float, Character)
int iNum = 10; // -> Integer
double dNum = 3.14; // -> Double
// 기본자료형 -> 포장
Integer w1 = new Integer(iNum); // int가 Integer로 포장됨
Double w2 = new Double(dNum); // double이 Double로 포장됨
// Wrapper 클래스 활용
System.out.println("int 최대값 : " + w1.MAX_VALUE);
System.out.println("double 최소값 : " + w2.MIN_VALUE);
// 기울어진 글씨 : static !
// static 은 객체를 생성하지 않고도,
// 클래스명.필드명, 클래스명.메소드명() 호출 가능
System.out.println("int 최소값 : " + Integer.MIN_VALUE);
System.out.println("double 최대값 : " + Double.MAX_VALUE);
//************************************************************
// 데이터 파싱 (parsing) 데이터의 형식을 변환하는것
// String데이터를 기본자료형으로 변환!
// 1) 문자열 100을 int형식으로 변환하기
int num1 = Integer.parseInt("100");
System.out.println(num1); // 100 출력됨
// 2) 문자열 1.23445를 double형식으로 변환하기
double num2 = Double.parseDouble("1.23445");
System.out.println(num2); // 1.23445 출력됨
// 3) 정상적으로 변환되었는지 확인하기
// 아직 문자열이면 이어쓰기 출력
// 각각 정수-실수형으로 변경되었으면 연산된 값이 출력됨
System.out.println(num1+num2); // 101.23445 출력됨
+ Wrapper 클래스의 AutoBoxing / AutoUnboxing
Integer w1 = new Integer(100);
// Integer에 삭제선 발생 (deprecated)
// == 해당 구문은 삭제될 예정이다 (사용을 권장하지 않는다)
Integer w2 = 100;
Integer w3 = 100;
// w2는 Integer형 참조형 변수 / 100은 int형 정수로
// 자료형이 다른 w2와 100사이에 연산이 안되어야 하지만
// Integer는 int의 포장된 형식이라는 것을 Java가 인식하고 있어서
// 위와 같은 경우 int를 Integer로 자동포장 해준다. (AutoBoxing)
System.out.println("w2+w3="+ (w2+w3));
// w2 (Integer 객체)
// w3 (Integer 객체)
// w2 + w3 출력시 객체 + 객체 끼리의 연산으로
// 덧셈이 아닌 이어쓰기가 출력돼야 하지만
// Java는 Integer는 int의 포장형태 라는것을 인식하고 있음
// + 연산시 포장을 자동으로 벗겨냄 (AutoUnboxing)
// Integer + Integer -> int + int
ex ) Set을 이용해 간단히 로또 번호 생성하기 + ( LinkedHashSet / TreeSet 응용 )
public void lotto() {
Set<Integer> lotto = new HashSet<Integer>();
// Integer는 equals, hashCode() 오버라이딩 완료상태
while(lotto.size()<6) {
// 중복 발생시 6개의 수가 저장되지 않으므로,
// 빈공간이 생기지 않도록 while문을 사용해
// lotto에 저장된 값이 6개 미만이면 반복
int random = (int)(Math.random()*45+1);
// 1 - 45 사이 난수 생성
System.out.println("random =" +random);
lotto.add(random);
// int값이 자동으로 Integer에 포장되어 lotto에 추가 (AutoBoxing)
}
System.out.println("로또번호 : "+ lotto);
}
// ---------------------------------------------------------------
// 이 때,
// Set<Integer> lotto = new LinkedHashSet<Integer>();
// LinkedHashSet 을 사용하면 순서가 유지되는 Set 를 생성할 수 있고,
// Set<Integer> lotto = new TreeSet<Integer>();
// TreeSet을 사용하면 자동 정렬이 되어있는 Set 을 생성할 수 있다.
▶ Map
1) 정의
- 키 와 값의 쌍으로 구성된 자료구조
2) 특징
- 키는 중복 저장을 허용하지 않음 ( Set 방식 )
- 값은 중복 저장을 허용함 (List 방식)
3) Map의 후손
HashMap< K, V > | Map의 자식 클래스 중 가장 대표되는 Map |
4) HastMap< K, V >
- 작성법
Map< ket 타입 , value 타입> [변수명] = new HashMap< key타입 , Value타입 > ();
- 자주 사용되는 메서드
1. Map.put : Map에 객체를 추가
Map<Integer, String> map = new HashMap<Integer, String>();
// Map.put(integer Key, String Value) : 값 추가
map.put(1,"홍길동");
map.put(2,"고길동");
map.put(3,"김길동");
map.put(4,"박길동");
map.put(5,"이길동");
map.put(6,"최길동");
// key 중복 -> 비허용; 새로 입력한 값 덮어쓰기
map.put(1,"홍홍홍"); // 1, 홍길동이 1, 홍홍홍으로 덮어쓰기됨
// value 중복 -> 허용;
map.put(7,"최길동"); // 7, 최길동이 map에 추가된다
System.out.println(map);
// map.toString() 호출됨
// {1=홍홍홍, 2=고길동, 3=김길동, 4=박길동, 5=이길동, 6=최길동, 7=최길동} 출력
2. Map.get(Object key) : Map을 이용해 Object key의 값 가져오기 (일회성 VO 생성)
// VO (값 저장용 객체)는 특정 데이터 묶음의 재사용이 많은 경우 사용
// -> 재사용이 적은 VO는 코드 낭비 . . .
// -> Map을 이용해 VO와 비슷한 코드를 작성할 수 있다.
//------------------------------------------------------
// 1) VO 버전
Member mem = new Member();
// 값 세팅
mem.setId("user01");
mem.setPw("pass01");
mem.setAge(30);
// 값 출력
System.out.println(mem.getId()); // user01 출력
System.out.println(mem.getPw()); // pass01 출력
System.out.println(mem.getAge()); // 30 출력
//------------------------------------------------------
// 2) Map 버전
Map<String, Object> map = new HashMap<String, Object>();
// 값 세팅
map.put("id", "user02");
map.put("pw", "pass02");
map.put("age", 25); // int -> Integer AutoBoxing (Object의 자손객체)
// 값 출력
System.out.println(map.get("id").toString());
System.out.println(map.get("pw"));
System.out.println(map.get("age"));
// 실행전 : Object의 toString() 실행 == 정적바인딩
// 실행후 : Member의 toString() 실행 == 동적바인딩 (자식 toString() 호출)
3. keySet() : Map의 key만 모아서 Set으로 반환
// Map에 저장된 데이터 순차적으로 접근하기
// Map에서 Key만 모아두면 Set의 특징을 가짐
// => keySet()메서드를 통해 key만 모아서 Set으로 반환
Set<String> set = map.keySet();
System.out.println(set); // [pw, id, age] 출력
for(String key :set) {
System.out.println(map.get(key));
// key가 반복될 때 마다 변경된 key에 맞는 map의 value출력
// (pass02, user02, 25)
// 순서는 저장되지 않기 때문에 뒤죽박죽으로 나옴...
}
// Map에 저장된 데이터가 많거나,
// 어떤 key가 있는지 불분명하거나,
// 또는 Map에 저장된 모든 데이터에 접근해야 할 때
// keySet() + 향상된 for문 코드를 사용한다.
4. List와 Map의 활용 ( List안에 Map 중첩하기)
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
// List안에 Map을 중첩하여 list 생성
for(int i = 0; i <10 ; i ++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("id", "user0"+i); // id, user01.. user02.. 대입
map.put("pw", "pass0"+i); // pw, pass01.. pass02.. 대입
// 만들어진 Map을 리스트에 추가
list.add(map);
}
// for문 종료시 Lis에는 10개의 Map객체가 추가되었다.
// 향상된 for문을 이용해
// List에 저장된 Map에서 key가 "id"인 경우의 value를 모두 출력
for(Map<String, Object> temp: list) {
System.out.println(temp.get("id"));
// pw만 출력하고 싶으면 temp.get("pw")를 출력하면 된다.
}
'Java > 공부' 카테고리의 다른 글
[SERVLET / JSP] 간단 정리 (0) | 2022.06.03 |
---|---|
[JDBC] 정리 (0) | 2022.04.03 |
[Java] 바인딩 (Binding) 0315_1 (0) | 2022.03.21 |
[Java] 다형성 (Polymorphism) (0) | 2022.03.21 |
[Java] 상속 (Inheritance) (0) | 2022.03.21 |