본문 바로가기
java

[JAVA] Collection, Iterator , JAVA (hashmap, treemap, 디자인패턴-싱글턴)

by CodeMango 2023. 2. 8.

Collection(수집)

ArrayList : 검색 , 선형구조 , 더 많이 씀

LinkedList(CRUD) :  실시간 추가, 삭제 , 선형구조

 

참조1 : https://crazykim2.tistory.com/557

참조2 :https://bangu4.tistory.com/194

 

Hashmap(java)

https://www.youtube.com/watch?v=oLH9Y8tD9Kw 참조

Hashmap은 사전이라는 뜻을 가지고 있습니다. 웹에서 사용하는 Json이라고도 불립니다.

자바에 Hashmap이 있다면 web에는 Json이 있습니다!

 

key     :     value   -  pair로 관리

사과   :   apple

 

특징

* 키와 값의 한 쌍으로 관리된다.

* HashMap(동기화X)은 Hashtable(동기화O)의 신버젼

* key 값은 중복 되지 않는다. 

* 값은 중복은 허용한다.

* tree구조를 갖는다. ( list는 선형구조)

선형구조는 중간부터 검색하지 못한다. 순서대로 검색할 수 있다.

그러나 tree구조는 key값만 알면 중간부터 검색할 수 있어서 검색속도가 빠르다.

* 순서를 유지하려면, LinkedHashMAp클래스를 사용하면 된다.

 

형식

HashMap map = new HashMap();

map.put("myId", "1234");
map.put("asdf", "1111");
map.put("asdf", "1234");  // 같은 키는 저장되지 않고 asdf가 1234로 변경된다.

 

Entry[ ] 에  Hashmap의 배열이 쌍으로 저장됩니다.

 

해싱

함수를 이용해서 저장하고 읽어오는 것

해시 함수로 해시테이블(linked list의 묶음) 에 있는 데이터를 저장, 검색

 

사용방법

1. 키로 해시함수를 호출해서 해시코드를 얻는다.

2. 해시코드(해시함수의 반환값)에 대응하는 링크드리스트를 배열에서 찾는다.

3. 링크드리스트에서 키와 일치하는 데이터를 찾는다.

* 해시함수는 같은 키에 대해 항상 같은 해시코드를 반환해야 한다.

 서로 다른 키일지라도 같은 값의 해시코드를 반환할 수도 있다.

 

 

장점

* String 이든 Integer 이든 ArrayList이든  map에다 담을 수 있다.

	//HashMap의 장점
	// String 이든 Integer 이든 ArrayList이든  map에다 담을 수 있다.
	String str = "Hello";
	Integer in = 123;
	ArrayList<String> list = new ArrayList<String>();

	//Q. Map<K, V> 는 어떻게 설정할까?
	//-> 문자열로 관리하면서 어떤 object든 넣을 수 있게 하는 것이 선호된다.
	Map<String, Object> map = new HashMap<String, Object>();
	
	map.put("문자열", str);//put:추가하기
	map.put("숫자", in);
	map.put("목록", list);

 

 

참조1: https://coding-factory.tistory.com/556

참조2: https://reakwon.tistory.com/151

 

[Collection] 이것만 알면 해시맵(HashMap) 정복 가능 - HashMap의 특징, 사용법 예제

해시맵(HashMap) 해시맵은 이름 그대로 해싱(Hashing)된 맵(Map)입니다. 여기서 맵(Map)부터 짚고 넘어가야겠죠? 맵이라는 것은 키(Key)와 값(Value) 두 쌍으로 데이터를 보관하는 자료구조입니다. 여기서

reakwon.tistory.com

 

HashMap 함수

참조 : https://www.youtube.com/watch?v=el6cTtPHVRs 

1. containsKey(key) : 맵에서 인자로 보낸 키가 있으면 true 없으면 false를 반환합니다.

		String value = hMap.get(101);
		
		boolean b = hMap.containsKey(102);
		if(b == true) {
			String val = hMap.get(102);
			System.out.println("value:" + val);

 

2. containsValue(value)

맵에서 인자로 보낸 값이 있으면 true 없으면 false를 반환합니다.

 

3. put()

		fMap.put("apple", "사과");
		fMap.put("pear", "배");

key : apple , value: 사과 // key: pear, value : 배

        hMap.put(103, "Bears");
		hMap.put(104, "Twins");

key : 103, value: Bears // key: 104, value : Twins

 

4. entrySet() : key와 value의 값 모두 출력

 

5. keySet() : key의 값만 출력

 

6. Iterator :  자바의 컬렉션 프레임워크에서 컬렉션에 저장되어 있는 요소들을 읽어오는 방법

 

Iterator , Listliterator, Enumeration

https://www.youtube.com/watch?v=k5qxJ53RYNc 

- 컬렉션에 저장된 데이터에 접근하는데 사용되는 인터페이스

- Enumeration은 Iterator의 구버전

- ListIterator는  Iterator의 접근성을 향상시킨 것( 단방향 -> 양방향)

 next는 한쪽방향으로만 가는데 ListIterator next()와 이전요소 previous()가 다 있습니다.

 

 

Iterator 

컬렉션에 저장된 요소들을 읽어오는 방법을 표준화한 것

컬렉션은 list, set, map 이 있는데 이 컬렉션마다 구조가 다릅니다. 

list ( arraylist, linkedlist) set(treeset) , map(hashmap) 등 종류가 많은데 이를 표준화한 것이 Iterator입니다.

메서드 설명
boolean hasNext()   1. 확인 읽어올 요소가 남아있는지 확인한다. 있으면 treu, 없으면 false를 반환한다.
Object next()            2. 읽기 다음 요소를 읽어온다. next()를 호출하기 전에 hasNext()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전하다.
void remove() next()로 읽어온 요소를 삭제한다. next()를 호출한 다음에 remove()를 호출해야한다.(선택적 기능)
void forEachRemaining(Consumer<? superE> action) 컬렉션에 남아있는 요소들에 대해 지정된 작업(action)을 수행한다. 람다식을 사용하는 디폴트 메서드.

 

참조 : https://www.techiedelight.com/ko/iterate-map-using-keyset-java/

 

keySet() 메소드를 사용하여 Java에서 맵 반복

이 게시물은 다음을 사용하여 맵을 반복하는 다양한 방법에 대해 설명합니다. keySet() Java에서. 우리는 알고 있습니다 keySet() 메소드는 맵에 포함된 키의 세트 보기를 리턴합니다. 따라서 다음을

www.techiedelight.com

참조2  : https://needjarvis.tistory.com/636

 

[Java] 자바에서 Map 반복 시키는 방법들

자바에서 Map 데이터를 loop를 돌리면서 가져오는 방법은 한가지만 있는 것이 아니다. 게다가 Stream이 지원이 되는 1.8부터는 더더욱 그 방법들이 늘어났는데 방법들을 정리해보고, 성능을 비교해

needjarvis.tistory.com

맵 반복 (전체출력)

	Iterator<Integer> it = hMap.keySet().iterator();  // key값을 따라가야함
	while(it.hasNext()) {   // 다음 데이터가 있니?
		Integer key = it.next();   // 첫번째 key값 꺼내면서 다음 주소로 이동
		String value = hMap.get(key);
		System.out.println(key + ":" + value);	
	}

 

iterator() 함수를 통해서 Iterator 반복자를 갖고 올 수 있습니다.

hasnext() 함수를 통해서 항목이 있는지 확인을 하고 next() 함수를 통해서 요소를 하나씩 하나씩 갖고 옵니다.

 

TreeMap

HashMap 에 sorting 기능이 추가되는 개념입니다.

다만, key값만 정렬 가능하다. (value값은 정렬 x)

생성자 부분에 HashMap을 넣어서 작동 가능합니다.

TreeMap<String, String> tMap = new TreeMap<String, String>( fMap );
					-- > fMap = Hashmap

 

특징

* key값을 기준으로 정렬한다.

* 주로 hasymap을 넘겨받아 정렬한다.

* 기본 데이터는 바뀌지 않는다.

* 범위 검색과 정렬에 유리한 컬렉션 클래스

*HasyMap보다 데이터 추가, 삭제에 시간이 더 걸림

* HasyMap과 호환된다.

* 평소에 잘 쓰이지는 않지만, HashMap을 쓰다가 sorting이 필요하면 TreeMap을 쓸 때가 많다.

 

 

<HashMap 예제>

CRUD 만들기

	//	HashMap<Integer, String> hMap = new HashMap<Integer, String>(); //방법1
		
		Map<Integer, String> hMap = new HashMap<Integer, String>();     //방법2
		
		// 추가
		hMap.put(101, "Lions");
		hMap.put(102, "Tigers");
		hMap.put(103, "Bears");
		hMap.put(104, "Twins");
		
		hMap.put(102, "Giants");
				
		System.out.println(hMap.size());
		
		// 모두 출력
		// iterator : 반복자(== 포인터(주소)) == cursor
		Iterator<Integer> it = hMap.keySet().iterator();
		while(it.hasNext()) {
			Integer key = it.next();
			String value = hMap.get(key);
			System.out.println(key + ":" + value);
		}
		
		// 삭제
		String deleteVal = hMap.remove(104);
		System.out.println("삭제된 value:" + deleteVal);
		
		// 검색
		//     value            key 
		String value = hMap.get(101);
		
		boolean b = hMap.containsKey(102);
		if(b == true) {
			String val = hMap.get(102);
			System.out.println("value:" + val);
		}
		
		// 수정
		hMap.replace(103, "Eagles");
		
		it = hMap.keySet().iterator();
		while(it.hasNext()) {
			Integer key = it.next();
			String val = hMap.get(key);
			System.out.println(key + ":" + val);
		}
		
		// HashMap의 장(강)점
		String str = "Hello";
		Integer in = 123;
		ArrayList<String> list = new ArrayList<String>();
		
		Map<String, Object> map = new HashMap<String, Object>();		
		map.put("문자열", str);
		map.put("숫자", in);
		map.put("목록", list);

 

 

<과제>

Q. 과일 5개를 추가하고 CRUD 해라

// 과일 5개를 map 추가하고 crud
		// String(key), String(key)
		Map<String, String> fMap = new HashMap<String, String>();
		
		// 추가
		fMap.put("apple", "사과");
		fMap.put("pear", "배");
		fMap.put("grape", "포도");
		fMap.put("banana", "바나나");
		fMap.put("orange", "오렌지");
		
		Iterator<String> it1 = fMap.keySet().iterator();
		while(it1.hasNext()) {
			String key = it1.next();
			String v = fMap.get(key);
			System.out.println("key:" + key + " value:" + v);
		}
				
	// 검색
		//containsKey(key) : 맵에서 인자로 보낸 키가 있으면 true 없으면 false를 반환한다.
		boolean b1 = fMap.containsKey("peach");
		if(b1 == true) { // peach가 있다면
			System.out.println("같은 키값이 있습니다");			
		}else{			 // peach가 없다면
			fMap.put("peach", "복숭아");
			System.out.println("추가되었습니다");		
		}
	// 모두출력 : map반복문 
		it1 = fMap.keySet().iterator(); //<- 누가 만들어놨음. 그냥 이렇게 사용하자
		while(it1.hasNext()) {
			String key = it1.next();  //key값을 얻어옴
			String v = fMap.get(key); //value값을 얻어옴
			System.out.println("key:" + key + " value:" + v);
		}
		
// TreeMap : 정렬 -> HashMap인 fMap을 넣는다.
		TreeMap<String, String> tMap = new TreeMap<String, String>( fMap );
		
	
// original data (오름차순) // original data는 변경되지 않음	
// 		Iterator<String> it2 = tMap.keySet().iterator();
		
		it1 = fMap.keySet().iterator();
		while(it1.hasNext()) {
			String key = it1.next();
			String v = fMap.get(key);
			System.out.println("key:" + key + " value:" + v);
			
		} // while end
		
		
// 내림차순
								// keySet() 부분만 바꾸면됨
		Iterator<String> it2 = tMap.descendingKeySet().iterator();		
		
		while(it2.hasNext()) {
			String k = it2.next();
			String v = tMap.get(k);
			System.out.println("key:" + k + " value:" + v);
			
		} //while end
        
출력값 :
key:peach value:복숭아
key:orange value:오렌지
key:grape value:포도
key:banana value:바나나
key:apple value:사과

 

디자인패턴 -싱글턴

 

GoF 디자인 패턴의 분류

이 중에서 생성패턴의 싱글턴(Singleton)이 가장 중요하다.

 

* 생성(Creational) 패턴
객체 생성에 관련된 패턴
객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을 제공합니다.

  * 싱글턴(Singleton)
    전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴

a,b,c클래스가 있을 때 서로 데이터를 주고 받으려면 getter를 만들어서 주고 받으면 됩니다.

그런데, 객체를 주고받으려면 그렇게 하기가 어렵다. 이를 보완하기 위해 나온 것이 '싱글턴'입니다!

 

* 싱글턴의 구조 : 어느 클래스든 접근할 수 있도록 만들어 놓은 하나(single)의 클래스(인스턴스)

A,B,C 어디에서나 접근이 가능하도록 하는 클래스를 하나 만들어서 List라는 객체를 넣어놓습니다.

이후에 D라는 클래스가 추가되어도 싱글턴에 접근 가능합니다.

다시 말해서 클래스끼리 대화를 한다고 이해할 수 있습니다.

이렇게 싱글턴이라는 중간 역할을 거쳐서 a와 c 가, a와 d가 대화할 수 있습니다.

참조 : https://gmlwjd9405.github.io/2018/07/06/design-pattern.html

참조 : https://myhappyman.tistory.com/35

public class SingleTon {
	//전역 객체변수로 사용하기 위해 static 객체변수로 생성
	static SingleTon instance;
	
	//생성자를 priavte로 만들어 접근을 막는다
	private SingleTon(){}
	
	//getInstance 메소드를 통해 한번만 생성된 객체를 가져온다.
	public static SingleTon getInstance(){
		if(instance == null){ //최초 한번만 new 연산자를 통하여 메모리에 할당한다.
			instance = new SingleTon();
		}		
		return instance;
	}
}

 

 

댓글