14-2. 자바(java) : 컬렉션(Collection) - Set, Map 개념과 활용 정리

2024. 4. 24. 19:08·JAVA

 

 

 

14-1. 컬렉션(Collection) :: List

1. 컬렉션이란?자바에서 제공하는 자료구조를 담당하는 프레임워크자료구조 : 메모리상에서 동일 타입 자료를 구조적으로 처리하는 방법론저장 공간의 크기를 동적 관리기능처리가 간단하게

tt2-blogging.tistory.com

List 정리는 이전 글을 참고하세요

 

2) Set 계열

  • 집합 구조로 하나의 묶음들로 순서 없이 저장한다.
  • 필터가 있어서 중복 값을 넣어도 저장되지 않음(Null 포함)
  • 객체의 경우 중복 체크 메소드 오버라이딩 필요(equals, hashcode)
  • 하나를 뽑으려면 뭐가 나올지 모르니까 전체를 순회해야 한다. (Iterator, forEach 이용)
    → 대신 그룹을 통째로 호출할 때 유용하다
@ Iterator
//HashSet생성
HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,2,3));

System.out.println(set); //전체출력 [1,2,3]

// Iterator 사용
Iterator iter = set.iterator();    
while(iter.hasNext()) { //값이 있으면 true 없으면 false
    System.out.println(iter.next());
}

(1) 구현 클래스 종류

HashSet

  • 순서 없이 랜덤 출력됨
    • 원하는 값을 찾으려면 .contains()를 통해 확인을 먼저 해야한다.
//set내부에 값 1이 있는지 check : true 
System.out.println(set.contains(1));
  • List와 호환이 되기 때문에 중복값을 제거하기 위해 잠깐 이용되기도 함
List foodList = new ArrayList(); //list 생성

Set foods = new HashSet(foodList);  //list -> set
foodList = new ArrayList(foods); //set -> list
  • 혹은 정렬을 위해 List로 변환해서 정렬 진행할 수 있음
ArrayList<Integer> list = new ArrayList<>(set); Collections.sort(list, (o1,o2) -> o2 - o1); // 내림차순 정렬 
System.out.println(list.toString()); // [3, 2, 1] Collections.sort(list, (o1,o2) -> o1 - o2); // 오름차순 정렬 
System.out.println(list.toString()); // [1, 2, 3]

LinkedHashSet

  • 저장한 순서대로 출력 가능한 Set

TreeSet

  • 이진 트리를 기반으로 한 Set 컬렉션으로 왼쪽과 오른쪽 자식 데이터(노드)를 참조하기 위한 두개의 변수로 구성됨
  • 이진탐색트리(TreeMap)의 문제점**을 보완한 레드-블랙 트리 형태
    → 부모 노드보다 작으면 왼쪽 자식, 크면 오른쪽 자식으로 배치하여 균형 맞춤(오름차순)
    • 트리가 높을 수록 시간이 오래 걸림
    • 트리의 데이터가 값이 편향되게 들어오면 한쪽으로 치우쳐져 비효율적인 포퍼먼스

  • Map.Entry 매칭 없이 값만 저장한다
  • 빠른 탐색 속도
  • 우선 순위가 있어야 출력할 수 있음
    • 우선순위 파악을 위한 메소드 필요: compareTo()

(2) Set 출력 방법

  • List와 달리 get()으로 뽑아올 수가 없어서 순회해야함
  • forEach이용 가능

(1) Iterator

//<String>이 빠지면 Object type이 되기 때문에 String으로 형변환을 거쳐야한다. 
//안하려면 제네릭 선언 필수 
Iterator<String> fruitIter = keys.iterator(); 
while(fruitIter.hasNext()) {
    Fruit f = fruits.get(fruitIter.next()); //키 하나씩 가져오기 
    System.out.println(f.getPrice() + f.getLocation()); 
}

(2) forEach

for(Object o : set) { 
        System.out.println(o); 
    } 
//방법2를 좀더 간결히 하려면
set.forEach(e -> System.out.println(e));

(3) keyset()

//key들을 모두 가져옴 
System.out.println("출력 1:"); 
Set<String> keys = fruits.keySet(); 
for(String k : keys) { 
    Fruit f = fruits.get(k); 
    System.out.println(f.getName() + f.getPrice()); 
}

(4) Map.Entry 이용

//마찬가지로 제네릭이 2개다, set의 제네릭으로 entry가 들어간 것임 
Set<Map.Entry<String, Fruit>> entry = fruits.entrySet(); 
for(Map.Entry<String, Fruit> e : entry) {
    //제네릭이 있어서 형변환 없이 바로 가능 
    String k = e.getKey(); 
    Fruit f = e.getValue(); 
    System.out.println(k + " " + f); 
 }

3) Map 계열

디비에서도 많이 쓰니까 알아둬야한다. (디비 정보저장)

 

key-Value 형식으로 키와 값이 매칭되어있는 형태 (쌍형)

  • map으로 묶어져있으며 key들이 소속되어 특정 값과 매칭되어 있음
  • key : 일종의 구분값(변수명)으로 중복 불가
    • 중복되면 value가 새로운 값으로 덮어쓰기 됨
    • 키를 먼저 가져와야 값을 가져올 수있음 → keySet()
      → keySet()을 forEach로 순회하면서 하나씩 출력할 수도 있음
    • 람다식 이용시 매개변수가 두개가 된다(키, 밸류)
//출력 람다식 
fruit.forEach((k,v) -> { System.out.println(k + " " + v); });
  • value: 중복 가능
  • 🚨 Collection인터페이스와 관계 없어서 호환 안됨
//map 사용한 DB 저장 예시 (한개 정보)
Map row = new HashMap();
row.put("memberId", "admin");
row.put("memberPwd", "1234");
row.put("age", 19);
row.put("hobby", List.of("코딩", "영화"));
ArrayList list = new ArryaList();
list.add(row);

//여러개 정보
ArrayList list = new ArrayList();
list.add(row);
row = new hashMap();
row.put("memberId", "admin");
row.put("memberPwd", "1111");
row.put("age", 20);
list.add(row);
System.out.println(list); //출력시 두개 데이터 나옴

1) 구현 클래스 종류

(1) HashMap

  • Map의 대표적인 컬렉션 중 하나. 해시테이블 구조의 자료형.
  • 말그대로 해싱hashing을 사용하기 때문에 많은 양의 데이터 검색시 유용하다.
  • 해시 함수를 통해 키와 값이 저장되므로 사용자는 정확한 위치를 알 수 없다. → 입력 순서 보장 X

원래 해시테이블 자료구조는 입력순서에 관여하지 않는다. 또한 자바 초기의 자료형이라 지금은 쓰지 않음

  • 저장공간보다 추가로 값이 들어오면 크기를 두배로 늘리며 과부하가 발생할 수 있으므로 초기에 데이터 개수를 안다면 용량을 지정해주는 것이 좋다.
//HashMap Map엘리먼트 삽입의 예
Map<String, Integer> a = new HashMap<>();
a.put("a", 1);
a.put("b", 2);

(2) TreeMap

이진 트리를 기반으로 한 Map 컬렉션으로, 키와 값이 저장된 Map.Entry를 저장하고 왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성된다.

  • 일반적인 Map으로 HashMap보다 성능이 떨어지나 정렬상태로 유지하거나 정렬된 데이터 조회하는 범위 검색 사용시 효율적이다.
    • 데이터 저장시 즉시 정렬이 진행되기 때문에 추가나 삭제가 HashMap보다 오래 걸린다.
  • key는 저장과 동시에 자동으로 값에 따라 오름차순 정렬한다.
    • 숫자 타입 → 값, 문자열 타입 → 유니코드 정렬
    • Integer, Double, String은 이미 Comparable 인터페이스를 통해 오름차순이 구현되어 있음
    • TreeSet, TreeMap은 내림차순은 따로 구현해야함

➕ Map 계열 내림차순 구현 방법
TreeSet, TreeMap 생성시 매개변수 생성자를 통한 재정렬 가능 - 혹은 Integer, Double, String 외 Comparable을 구현하는 객체는 compareTo()메소드 오버라이딩으로 내림차순 구현

//TreeMap Map 엘리먼트 삽입 예
Map<String, Integer> b = new TreeMap<>();
b.put("a", 1);
b.put("b", 2);

(3)LinkedHashMap

입력순서가 유지되는 맵의 일종

2) Map 제공 메소드

(1)put(key값, value) : 데이터 넣기

List, Set은 add()를 쓴다는 점에서 차이가 있다.

  • key: 기본 Object
    → 보통 숫자(Integer)나 문자열(String)로 관리, 문자열이 더 찾기 쉬움
    • 마찬가지로 중복 불가, 중복시 덮어쓰기 됨
  • value: 기본 Object
    → Vo객체나 기본값
//Map구조
HashMap map = new HashMap();
Map m = new HashMap();
//Collection과는 호환되지 않는다

//Map저장소에 값 저장하기: put(key, value)     
map.put("오순", new Animal("오순",15.3, 2, "강아지"));
//key값은 중복이 불가능하다. (덮어쓰기됨)
map.put("오순", "김명준");
System.out.println(map.get("오순")); //김명준

//출력
System.out.println(map);
//{오순=오순, 15.3, 2, 강아지, 도토리=도토리, 0.3, 3, 햄스터}
  • keySet() : 모든 key 한번에 가져오기(Set 형식으로)
    • set형식은 get이 없어서 원하는 값을 뽑아올 수 없음 -> 전체 순회 필요
//key 한번에 가져오기 -> set 방식으로 가져와줌
Set keys = snack.keySet();
System.out.println(keys);
//set형식은 get이 없어서 원하는 값을 뽑아올 수 없음 -> 전체 순회
  • get(key): 데이터 가져오기
//data 가져오기 -> key 값을 바탕으로 값을 가져온다
//get(key)
Object o = map.get("오순"); //아래처럼 해도 됨
Animal o2 = (Animal) map.get("오순");
System.out.println(o);
System.out.println(o2.getName() + " " + o2.getAge());
  • size() : 저장된 데이터 수 확인하기
  • remove(key값) : 데이터 삭제하기
  • containsKey(): 해당하는 key 값이 있는지 확인하기
  • System.out.println(map.containsKey("도토리")); //true
  • containsValue(): 해당하는 값이 있는지 확인하기
  • entrySet() : key와 value값을 Map.Entry 객체로 반환해주는 메소드 -> key, value가 모두 필요할 때 사용

Map 순회하기

  1. entrySet()을 이용하여 내부 키-값 형태를 Entry<K, V>를 지닌 집합 자료형, 즉 Set으로 만든 다음에 순회할 수 있다.
  2. map.keySet(), map.get()을 이용해 map의 key들을 모아서 순회
// for loop (keySet())        
Set<Integer> keySet = map.keySet();        
for (Integer key : keySet) {
    System.out.println(key + " : " + map.get(key));        
 }

Map에 저장된 모든 키-밸류 쌍을 갖고 있는 하나의 객체로 얻을 수 있게 해줌

getKey(), getValue() 2개의 메소드를 통해 키와 값에 접근할 수 있다.

setVaule(값): Map.Entry 객체의 key에 대한 value 값을 수정할 수 있다.

  • key값을 얻어온 뒤에 value를 가져오지 않고 한번에 값을 수정할 수 있다.

이용해보기

  • 일단 Set으로 선언을 해준다.
Set entry = snack.entrySet();
  • iterator, forEach문, forEach 메소드 활용하여 가져올 수 있음
//entrySet()
//1. 이터레이터 이용
System.out.println("Map.Entry 이요해서 전체 데이터 가져오기");
Set entry = snack.entrySet();
Iterator it2 = entry.iterator();
while(it2.hasNext()) {
    //형변환으로 엔트리 안에 맵 키와 밸류 정보 저장
    Map.Entry e = (Map.Entry) it2.next(); 
    System.out.println(e.getKey() + " : " + e.getValue());
}

//2. for each
for(Object o1 : snack.entrySet()) {
    Map.Entry e = (Map.Entry) o1; //반복문에 돌면서 하나씩 들어감
    //entry는 키와 밸류를 따로 가져올 수 있는 능력이 있음
    System.out.println(e.getKey());
    System.out.println(e.getValue());
}
  • keySet() : 키의 값만 필요할 때 사용하지만 get(key)와 함께 value를 출력하기도 한다.
    • 다만, key로 value를 따로 찾는데서 시간이 소요되므로 데이터량이 많으면 entrySet()이 좋다.

4) Properites 클래스 (프로퍼티 클래스)

키와 값을 String 타입으로 제한한 Map컬렉션 형식의 클래스

프로퍼티(*.properites)파일 읽을때 주로 사용함(DB 접속 드라이버 데이터 읽기 등)

  • 파일과 연동되는 메소드가 있어서 연동관리가 편리함
  • 문자열 데이터를 저장관리할 때 : 프로그램에 대한 설정 내용(옵션정보), 데이터베이스 연결정보, 다국어 정보 등
  • 애플리케이션에서 주로 변경이 잦은 문자열을 저장하여 관리하기 때문에 유지보수를 편리하게 만들어줌
  • 키와 값이 ‘=’기호로 연결되어있는 텍스트파일로 기본적으로는 ISO 8859-1문자셋으로 저장됨

➕ property 파일
: 세미콜론, 엔터 안함(엔터 대신 띄어쓰기하고 역슬러시 사용)

(1) 사용 메소드

  • 값 저장 : put()
//문자열데이터 저장관리 용도- > 파일과 연동되는 메소드가 있어서 연동관리 편리
//클래스이므로 아래와 같이 생성
Properties prop = new Properties();
//값 저장 : put()
prop.put("name", "유병승");
//혹은 setProperty(): 문자열 저장
prop.setProperty("email", "teacherDev09@gmail.com");
prop.setProperty("address", "경기도 시흥");

 

  • 값 가져오기 : getProperty(key)
//값 가져오기
String email = prop.getProperty("email");
System.out.println(email);
  • 전체 순회 :  별로 쓸일 많지 않음
for(Object key : prop.keySet()) {
    String k = (String) key;
    System.out.println(prop.getProperty(k));
}
System.out.println("출력");
prop.forEach((k,v) -> System.out.println(k + " " + v));
  • 특정 파일에 저장(properties)
    : store(FileWriter or FileOutputStream) 
    : 
    stroeXML(FileWriter of FileOutputStream)
    • 단, 사용 후 꼭 닫아줘야함
    • 없으면 파일이 자동 생성됨
//특정 file에 저장 :  store(fileWriter 혹은 fileOutputStream), 	함께 이용(원하는대로)
//단, 사용 후 꼭 닫아야함
//혹은 stroeXML() : 저장할 파일이 xml형식일 때 사용
//자동으로 파일 생성되었음
try(FileOutputStream fos = new FileOutputStream("test.properties")){
        prop.store(new FileOutputStream("test.properties"), "test");
} catch(IOException e) {
    e.printStackTrace();
}

//xml은 writer 못씀 : xml방식으로 저장하기
try(FileOutputStream wf = new FileOutputStream("test.xml");) {
    prop2.storeToXML(wf, "xmlfile");
} catch(IOException e){
    e.printStackTrace();
}
  • 특정 파일 읽어오기
    : load(FileReader or FileOutputStream)
    : loadFromXML(FileOutputStream)
//properites파일 읽어오기: load(FileInputStream, FileReader) 
//매개변수로 넣어주면 연동된 파일을 가져온다.
//추상화되어있기 때문에 프로그램 돌아가는 세팅할 때 유용할 수 있다
Properties prop2 = new Properties();
try(FileInputStream fis = new FileInputStream("test.properties")){
    prop2.load(fis);
}catch(IOException e) {
    e.printStackTrace();
}
System.out.println(prop2);


//xml데이터 가져오기 : 태그를 만들어줘야되서 reader 못씀
Properties xmlprop = new Properties();
try(FileInputStream fis = new FileInputStream("test.xml")) {
    xmlprop.loadFromXML(fis);
}catch(IOException e) {
    e.printStackTrace();
}
System.out.println(xmlprop.getProperty("address"));


//프로젝트 폴더 위치에 properties 파일 직접 생성한 뒤 불러오기
Properties driver = new Properties();
try(FileInputStream fis = new FileInputStream("driver.properties")){
    driver.load(fis);
} catch(IOException e) {
    e.printStackTrace();
}
System.out.println(driver.getProperty("driver"));
System.out.println(driver.getProperty("path"));
System.out.println(driver.getProperty("url"));
}

5) 그 외 알아두면 좋을 Collections 클래스 전용 메소드

  • 특정 문자열의 중복값 갯수를 세어주는 메소드 : .frequency(  , )
int count = Collections.frequency(List, String);
  • 최대값: max(), 최소값 : min()
// HashMap 준비        
Map<Integer, Integer> map = new HashMap<Integer, Integer>();        
map.put(1, 5);
map.put(2, 70);        
map.put(3, 50);
// Max Key        
Integer maxKey = Collections.max(map.keySet());         
// Min Key        
Integer minKey = Collections.min(map.keySet());         
// 결과 출력        
System.out.println(maxKey); // 3        
System.out.println(minKey); // 1
반응형

'JAVA' 카테고리의 다른 글

16. 자바(java) : java.lang 패키지 클래스 정리(Object, System, Class, String, Wrapper, Math)  (0) 2024.04.24
15. 자바(java) : java.util 패키지 클래스 정리(Date, Calendar, GregorianCalendar, SimpleDateFormat, stream)  (0) 2024.04.24
14-1. 자바(java) : 컬렉션(Collection) - List 개념과 활용 정리  (0) 2024.04.09
13. 자바(java) : 문자열 및 파일 입출력(IO)을 위한 스트림(stream) 간단 정리  (0) 2024.04.09
12. 자바(java) : 예외(Exception) 처리, try-catch문 간단 정리  (0) 2024.04.09
'JAVA' 카테고리의 다른 글
  • 16. 자바(java) : java.lang 패키지 클래스 정리(Object, System, Class, String, Wrapper, Math)
  • 15. 자바(java) : java.util 패키지 클래스 정리(Date, Calendar, GregorianCalendar, SimpleDateFormat, stream)
  • 14-1. 자바(java) : 컬렉션(Collection) - List 개념과 활용 정리
  • 13. 자바(java) : 문자열 및 파일 입출력(IO)을 위한 스트림(stream) 간단 정리
JinHyung-dev
JinHyung-dev
틈틈이 기록하고 있습니다!!
  • JinHyung-dev
    JinHyung's 블로그
    JinHyung-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (34)
      • JAVA (18)
      • Oracle DataBase (12)
      • 프리코스 (4)
  • 인기 글

  • 반응형
  • 최근 댓글

  • 최근 글

  • 태그

    DB
    백엔드
    공부
    SQL
    자바
    요약
    정리
    oracle
    개발자
    Java
  • hELLO· Designed By정상우.v4.10.0
JinHyung-dev
14-2. 자바(java) : 컬렉션(Collection) - Set, Map 개념과 활용 정리
상단으로

티스토리툴바