List, Map, SetWEB JAVA SPRING/문법2023. 8. 24. 16:31
Table of Contents
== 데이터의 집합==
Java Collection에는 List, Map, Set 인터페이스를 기준으로 여러 구현체가 존재한다.
이에 더해 Stack과 Queue 인터페이스도 존재한다.
Q.왜 이러한 Collection 을 사용하는 것일까?
A1.다수의 Data 를 다루는데 표준화된 클래스들을 제공해주기 때문에 DataStructure를 직접 구현하지 않고
편하게 사용할 수 있기 때문이다.
A2.배열과 다르게 객체를 보관하기 위한 공간을 미리 정하지 않아도 되므로, 객체의 수를 동적으로 정할 수 있다. 이는 프로그램의 공간적인 효율성 또한 높여준다.
List
- 순서O, 데이터 중복O
- 가변적인 크기(ArrayList는 list를 배열 형태로 구현한 것으로 크기가 자동으로 조정된다.)
- 데이터를 순서에 맞게 저장, Index를 부여한다. -> 특정 index에 데이터를 삽입하거나 접근할 수 있다.
ArrayList
- 크기를 마음대로 조절할 수 있는 배열
- 단방향 포인터 구조로 자료에 대한 순차적인 접근에 강점이 있음
LinkedList
- 양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 빠른 성능을 보장.
- 메모리 많이 차지
- 스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임
문자열 ArrayList를 생성 | ArrayList list = new ArrayList(); |
생성된 ArrayList 객체에 데이터 순서대로 저장 |
add(data) |
특정위치에 추가 | set(index,data) |
~제거 | remove(index) |
가져오기 | get(index) |
크기 | size() |
저장된 위치 | IndexOf(데이터) |
- 그런데 ArrayList는 동일한 데이터가 여러 번 저장될 수 있기 때문에 맨 처음에 있는 데이터의 위치가 검색되어 반환된다. 검색을 반대 방향으로 하려면, lastIndexOf(데이터) 메소드를 사용한다.
실습1
import java.util.*;
import java.util.Vector;
public class MB_Exam17_Generi {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList <String> list = new ArrayList<String>();
int i , j;
///////////////////////////////
list.add("Milk"); //0번째 위치에다 Milk를 저장한다.
list.add("Bread"); //1번째 위치에다 Bread를 저장한다.
list.add("Butter"); //2번째 위치에다 Butter를 저장한다.
System.out.println("Size="+list.size());
for(i=0;i<=list.size()-1;i++) {
System.out.println("list["+i+"]="+list.get(i));
}
//////////////////////////
list.add(1,"apple"); //1위치에다 Apple을 추가한다. 크기가 1 증가하게 된다.
System.out.println();
System.out.println();
System.out.println("Size="+list.size());
for(i=0;i<=list.size()-1;i++) {
System.out.println("list["+i+"]="+list.get(i));
}
////////////////////////////////////////
list.set(2, "Sweet");//2위치에 있는것을 Sweet으로 수정한다. 크기는 그대로다.
System.out.println();
System.out.println();
System.out.println("Size="+list.size());
for(i=0;i<=list.size()-1;i++) {
System.out.println("list["+i+"]="+list.get(i));
}
///////////////////////////////////////////////
list.remove(1); //위치 1에 있는 원소를 제거한다. 그래서 크기는 1 줄어든다.
System.out.println();
System.out.println();
System.out.println("Size="+list.size());
for(i=0;i<=list.size()-1;i++) {
System.out.println("list["+i+"]="+list.get(i));
}
/////////////////////////////////////////////////
j=list.indexOf("Sweet);"
System.out.println();
System.out.println();
System.out.println("Size="+list.size());
for(i=0;i<=list.size()-1;i++) {
System.out.println("list["+i+"]="+list.get(i));
}
System.out.println("Index of Sweet = "+j) } }
출력
실습2
List 소스코드
package kr.co.mlec.day02;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/*
* List: 순서(o), 중복 (o)
* - ArrayList
* - LinkedList
*
* Wrapper class (기본자료형-> 참조자료형)
* 기본자료형 참조자료형(
* boolean Boolean
* char Character
* byte Byte
* short Short
* int Integer
* long Long
* float Float
* double Double
*
*
* class Integer {
* private int data;
* }
*/
public class ListMain { //클래스 이름 작성
public static void main(String[] args) { // 메인함수 작성
//List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>(); //변수 list의 쓰임이 뭘까 정의, ArrayList를 만들기 위한 변수
// JDK 1.7버전부터 뒤에는 작성 안해도 인식 가능, 제네릭
//묵시적 형변환 가능
//<>제너릭 오직 레퍼런스 타입만 가능하여 기본자료형인 int 사용 불가능
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("one"); //하나씩 데이터를 삽입해(add) 씀
//Arraylist는 중복가능
System.out.println("원소의 총 개수: "+ list.size()); //몇개있는지 size 씀
System.out.println("0번지 위치한 데이터: " + list.get(0)); // 0번째 가져왔다 get으로
String removestr = list.remove(0); // 0번째 지웠다. + 특징: 삭제 후에는 뒤에 있던 애들 앞으로 떙겨짐
System.out.println("0번지 삭제 데이터:" + removestr); // removerstr : 삭제 데이터를 저장해 놓겠다
System.out.println("0번지 삭제 후 0번지 위치한 데이터: " + list.get(0)); // 삭제된 데이터가 뭔지 보여주자
boolean bool = list.contains("three"); // bool: list에 저 three가 있냐
if(bool) { // if문: bool에 three있으면
System.out.println("three는 존재합니다");
}else {
System.out.println("three는 존재하지 않습니다.");
}
if(list.remove("three")) {
System.out.println("삭제 성공");
}else {
System.out.println("삭제 실패");
}
bool = list.contains("three"); //변수를 다시 가져다 쓴,,,
if(bool) {
System.out.println("three는 존재합니다");
}else {
System.out.println("three는 존재하지 않습니다.");
}
//전체데이터 출력하자
System.out.println("< 전체 데이터 출력 - 첫번쨰 방식 >");
for (int i = 0; i < list.size(); i++) { // size 만큼 돌리겠다
System.out.println(list.get(i)); // get으로 데이터 추출
}
System.out.println("< 전체 데이터 출력 - 두번쨰 방식 >"); // 출력할 때만 사용 가능
for (String str:list) { // 향상된 for문
System.out.println(str);
}
}
}
List - 콘솔 출력
원소의 총 개수: 5
0번지 위치한 데이터: one
0번지 삭제 데이터:one
0번지 삭제 후 0번지 위치한 데이터: two
three는 존재합니다
삭제 성공
three는 존재하지 않습니다.
< 전체 데이터 출력 - 첫번쨰 방식 >
two
four
one
< 전체 데이터 출력 - 두번쨰 방식 >
two
four
one
Map
- 키(key)와 값(value)의 쌍
- 순서X, key 중복X , value 중복O
- 검색 속도 빠름
- index 존재 X, iterator 사용
HashMap
- Map 인터페이스를 구현하기 위해 해시테이블을 사용한 클래스
- Key에 대한 중복이 없으며 순서를 보장하지 않는다.
- Key와 Value 값으로 NULL을 허용한다.
- 동기화가 보장되지 않는다.
- 검색에 가장 뛰어난 성능을 가진다.
HashTable
- 동기화가 보장되어 병렬 프로그래밍이 가능하고 HashMap 보다 처리속도가 느리다.
- Key와 Value 값으로 NULL을 허용하지 않는다.
LinkedHashMap
- 입력된 순서를 보장한다.
TreeMap
- 이진 탐색 트리(Red-Black Tree)를 기반으로 키와 값을 저장한다.
- Key 값을 기준으로 오름차순 정렬되고 빠른 검색이 가능하다.
- 저장 시 정렬을 하기 때문에 시간이 다소 오래 걸린다.
HashMap
put - key, value 추가
import java.util.HashMap;
public class Sample {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
}
}
get 으로 접근
import java.util.HashMap;
public class Sample {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.get("people")); // "사람" 출력
}
}
containsKey - 맵에 해당 key가 있는지를 참(true) 또는 거짓(false)으로 리턴한다.
(... 생략 ...)
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.containsKey("people")); // true 출력
remove - 맵의 항목을 삭제, 해당 key의 항목을 삭제한 후 value 값을 리턴한다.
(... 생략 ...)
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.remove("people")); // "사람" 출력
나머지 메소드 참고 : https://wikidocs.net/208
실습
Map 소스코드
package kr.co.mlec.day02;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/*
* Map: key, value 쌍으로 구성된 데이터의 집합
* 순서(x), key에 대한 중복(x)
* - HashMap
* - TreeMap
*/
public class MapMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> map = new HashMap<>(); //String 타입인 key,value map 변수로 저장 , HaspMap 클래스 생성
//키 //밸류
map.put("1", "ONE");
map.put("2", "TWO");
map.put("3", "THREE");
map.put("4", "FOUR"); // map에 4개 넣음
System.out.println("원소의 개수: " + map.size()); // map 안에 몇개 있음?
System.out.println("key : 1 ===> value : "+ map.get("1")); // key가 1일 때 value는? get(): value값 가져오기
System.out.println("key : 5 ===> value : "+ map.get("5")); // key가 5일 때 value는? 없음
map.put("1","하나"); // key 1 value 하나 추가용: put은 동일한 값이 있을 경우 새로운 값으로 대체하고 기존 값 반환
System.out.println("key : 1 ===> value : " + map.get("1"));
// key = 5인 데이터가 없으면 key:5, value: "FIVE" 삽입
if(!map.containsKey("5")) {
map.put("5","FIVE");
}
System.out.println("key : 5 ===> value : "+ map.get("5"));
System.out.println("<전체 데이터 출력 - 첫번째 방식>");
Set<Entry<String, String>> entry = map.entrySet();
//Set<Map.Entry<K, V>> entrySet() :(key 와 value) 쌍을 표현하는 Map.Entry 집합을 반환
//실제 entry에 있으니 entrySet으로 잡아 날라와라
// set 형이 가지고 있는 데이터 타입이 Entry
for(Entry<String,String> e :entry) {
System.out.println("key : " +e.getKey() + ", value: " + e.getValue()
);
}
System.out.println("<전체 데이터 출력 - 두번째 방식>"); //key 만 뽑아서 데이터 출력
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.println("key: " + key + ", value : " + map.get(key));
}
}
}
Map 콘솔
원소의 개수: 4
key : 1 ===> value : ONE
key : 5 ===> value : null
key : 1 ===> value : 하나
key : 5 ===> value : FIVE
<전체 데이터 출력 - 첫번째 방식>
key : 1, value: 하나
key : 2, value: TWO
key : 3, value: THREE
key : 4, value: FOUR
key : 5, value: FIVE
<전체 데이터 출력 - 두번째 방식>
key: 1, value : 하나
key: 2, value : TWO
key: 3, value : THREE
key: 4, value : FOUR
key: 5, value : FIVE
Map 소스코드(비밀번호 변경)
package kr.co.mlec.day02;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class MapMain02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String, String> members = new HashMap<>();
members.put("aaa","1111");
members.put("bbb","2222");
members.put("ccc","3333");
members.put("ddd","4444");
System.out.println("< 비밀번호 변경서비스 입니다 >");
System.out.println("회원님의 아이디를 입력하세요 : ");
Scanner sc = new Scanner(System.in);
String id = sc.nextLine();
if(!members.containsKey(id)) {
System.out.println("입력하신 아이디 [" + id + "]는 존재하지 않습니다.");
System.out.println("변경서비스를 종료합니다.");
System.exit(0);
}
System.out.println("현재 패스워드를 입력하세요 : ");
String password = sc.nextLine();
if(!members.get(id).equals(password)) {//문자열 비교시 equals 사용
System.out.println("패스워드가 일치하지 않습니다");
System.out.println("변경서비스를 종료합니다.");
System.exit(0);
}
System.out.println("변경할 패스워드를 입력하세요 : ");
String newPassword = sc.nextLine();
members.put(id,newPassword);
System.out.println("패스워드 변경이 완료되었습니다.");
System.out.println("< 회원 정보 출력 >");
System.out.println("----------------------------------");
System.out.println("\tID\tPASSWORD");
System.out.println("----------------------------------");
Set<String> keys = members.keySet();
for(String key : keys) {
System.out.println("\t" + key + "\t" + members.get(key));
}
System.out.println("----------------------------------");
}
}
Map 콘솔
< 비밀번호 변경서비스 입니다 >
회원님의 아이디를 입력하세요 :
ccc
현재 패스워드를 입력하세요 :
3333
변경할 패스워드를 입력하세요 :
1111
패스워드 변경이 완료되었습니다.
< 회원 정보 출력 >
----------------------------------
ID PASSWORD
----------------------------------
aaa 1111
ccc 1111
bbb 2222
ddd 4444
----------------------------------
Set
- 순서X, 데이터 중복X
- 검색 속도 빠름
- index 존재 X, iterator 사용
HashSet
- 인스턴스의 해시값을 기준으로 저장하기 때문에 순서를 보장하지 않는다.
- NULL 값을 허용한다.
- 가장 빠른 임의 접근 속도
LinkedHashSet
- 입력된 순서를 보장한다.
TreeSet
- 이진 탐색 트리(Red-Black Tree)를 기반으로 한다.
- 정렬된 순서대로 보관하며 정렬 방법을 지정할 수 있음
- 데이터 삽입, 삭제에는 시간이 걸리지만 검색, 정렬이 빠르다.
Set 소스코드
package kr.co.mlec.day02;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/*
* set : 순서(x), 중복(x)
* - HashSet
* - TreeSet 인터페이스
* - get 함수 x
*/
public class SetMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Set<String> set = new HashSet<>();
Set<String> set = new TreeSet<>();
set.add("one"); // Set에 "one" 데이터 추가
set.add("two");
set.add("three");
set.add("four");
set.add("five");
boolean bool= set.add("one"); // bool에 원이라는 데이터가 있는지 없는지 출력 확인하기 위해서~
System.out.println(bool ? "삽입성공" : "삽입실패"); //? 삼항연산자로 true 면 삽입~ false면 실패~
System.out.println("원소의 총 개수: " + set.size()); // size로 set 안에 원소 몇개 있는지 알랴줌
// 1.5 버전의 for문이용
System.out.println("< 전체 데이터 출력 - 첫번째 방식>");
for (String str :set) { //향상된 for문 - 문자열을 반복문 ㄱ
System.out.println(str); //hash 코드 값 기준으로 순서가 무작위로 나온다
// String으로 오름차순으로 출력됨.
// 2. toArray() 메소드 이용
System.out.println("<전체 데이터 출력 - 두번째 방식>");
Object[] arr = set.toArray(); //순서가 없는 상태인 애들을 배열로 넣어 사용 한다 --> index 와 향상된 for문 사용 가능
for (int i = 0 ; i< arr.length ; i++) {
System.out.println(arr[i]);
}
//for(int i = 0; i <arr.length ; i++){
//String str = (String)arr[i];
//System.out.println("[" + arr[i] + "]", length : " + str.length());}
}
/*
* Iterator(순환자) 주요메소드
* - hasNext():다음 데이터의 존재여부 판단
* - next() : 데이터 접근 (다음 데이터로 이동)
*
*/
System.out.println("<전체 데이터 출력 - 세번째 방식>");
Iterator<String> ite = set.iterator(); // 반복자
while(ite.hasNext()) { //무한반복인 while은 true를 받으니까 hasNext를 사용(hasNext: 불린타입으로 출력)
String str = ite.next();
System.out.println(str);
}
}
}
Set 콘솔 출력
삽입실패
원소의 총 개수: 5
< 전체 데이터 출력 - 첫번째 방식>
five
<전체 데이터 출력 - 두번째 방식>
five
four
one
three
two
four
<전체 데이터 출력 - 두번째 방식>
five
four
one
three
two
one
<전체 데이터 출력 - 두번째 방식>
five
four
one
three
two
three
<전체 데이터 출력 - 두번째 방식>
five
four
one
three
two
two
<전체 데이터 출력 - 두번째 방식>
five
four
one
three
two
<전체 데이터 출력 - 세번째 방식>
five
four
one
three
two
참고: https://cocoon1787.tistory.com/527, https://hackersstudy.tistory.com/26
'WEB JAVA SPRING > 문법' 카테고리의 다른 글
상속/생성자/인터페이스 (0) | 2023.08.25 |
---|---|
객체/클래스/인스턴스 (0) | 2023.08.25 |
Collection, Vector (0) | 2023.08.24 |
제네릭스 (1) | 2023.08.24 |
접근제어자 (0) | 2023.08.24 |