article thumbnail image
Published 2022. 9. 19. 23:10
주요내용
  • List인터페이스
  • Iterator
  • Set인터페이스
  • Map인터페이스
  • hashing
  • 컬렉션 문제풀이

 


 

컬렉션

여러 객체(데이터)를 모아놓은 것을 의미

 

컬렉션 프레임워크

컬렉션(다수의 객체)을 다루기 위한 표준화된 프로그래밍 방식

다양한 클래스 제공

 

 

컬렉션 프레임워크의 핵심 인터페이스

인터페이스 특징
List 순서가 있는 데이터의 중복 혀용
Set 순서x,중복 허용x
Map 키와 값의 쌍으로 이루어진 데이터의 집합
순서x,중복(키x,값o)

 

 

List인터페이스

 

Arraylist

저장공간으로 배열을 사용

 

생성하기 위해서는 저장할 객체 타입을 매개변수, 즉 제네릭으로 표기하고 기본 생성자를 호출

ArrayList<타입 매개변수> 객체명 = new ArrayList<타입 매개변수>(초기 저장 용량);

ArrayList<String> container1 = new ArrayList<String>();
// String 타입의 객체를 저장하는 ArrayList 생성
// 초기 용량이 인자로 전달되지 않으면 기본적으로 10으로 지정됩니다. 

ArrayList<String> container2 = new ArrayList<String>(30);
// String 타입의 객체를 저장하는 ArrayList 생성
// 초기 용량을 30으로 지정하였습니다.

 

추가시 값이 앞에서부터 차례로 저장

 

 

장점-배열은 구조가 간단하고 데이터를 읽는 데 걸리는 시간(접근시간)이 짧다.

         순차적 데이터 추가(끝에 추가)와 삭제(끝부터 삭제)는 빠르다

 

단점-크기를 변경할 수 없다.

        비순차적 데이터의 추가 삭제에 시간이 많이 걸림

 

 

 

 

LinkedList

배열과 달리 Linkedlist는 불연속적으로 존재하는 데이터를 연결(각 요소가 연속적이다.)

class Node{
	Node next;
    object obj;
}

 

장점-비순차적 데이터의 추가,삭제가 빠르다

 

단점-데이터가 많을수록 접근시간이 길어진다.

 

 

 

 

 

ArrayList vs. LinkedList

컬렉션 읽기(접근시간) 추가/삭제 비고
ArrayList 빠르다 느리다 순차적 추가 삭제는 더 빠름
비효율적인 메모리 사용
LinkedList 느리다 빠르다 데이터가 많을수록 접근성이 떨어짐

 

 

 

Iterator

 

컬렉션의 저장된 요소들을 순차적으로 읽어오는 역할

Collection 인터페이스에 정의된 iterator을 호출하면 , Iterator타입의 인터슨스가 반환

 

iterator()을 통해 만들어진 인스턴스는 다음과 같은 메서드를 사용

메서드 설명
hasNext() 읽어올 객체가 남아있으면true리턴, 없으면 false리턴
next() 컬렉션에서 하나의 객체를 읽어옴
이 때,hasNext()를 통해 읽어올 다음 요소가 있는지 먼저 확인이 필요
remove() next()를 통해 읽어온 객체를 삭제.
next()를 호출한 후 remove()를 호출해야 함.

 

 

 

 

Set 인터페이스

 

 

요소의 중복을 허용하지 않고, 저장 순서를 유지하지 않는 컬렉션

대표적인 Set을 구현한 클래스에는 HashSet, TreeSet이 있다.

 

 

HashSet

Set 인터페이스의 특성을 그대로 물려받은 클래스(중복X,저장순서X)

 

add메서드가 HashSet에 값을 추가할 때 중복값인지 확인하는 법!

 

저장 객체의 해시코드를 hashCode() 메서드를 통해 얻어낸 후

Set이 저장하고 있는 모든 객체들의 해시코드를 hashCode() 메서드로 얻어내어 비교

같지 않다면

equals() 메서드를 통해 객체를 비교!

같은 값이 있다면 false리턴하며 추가되지 않음

 

 

 

TreeSet

이진 탐색 트리 형태로 데이터를 저장

 

데이터의 중복 저장을 허용하지 않고 저장 순서를 유지하지 않는 Set 인터페이스의 특징은 그대로 유지

이진 탐색 트리(Binary Search Tree) 하나의 부모 노드가 최대 개의 자식 노드와 연결되는 이진 트리(Binary Tree) 일종으로, 정렬과 검색에 특화된 자료 구조

최상위 노드를 루트'

모든 왼쪽 자식의 값이 루트나 부모보다 작고, 모든 오른쪽 자식의 값이 루트나 부모보다 값을 가짐.

 

노드들은 node클래스를 인스턴스화한 인스턴스에 해당

class Node {
	Object element; // 객체의 주소값을 저장하는 참조변수
	Node left;      // 왼쪽 자식 노드의 주소값을 저장하는 참조변수
	Node right;     // 오른쪽 자식 노드의 주소값을 저장하는 참조변수
}

요소를 추가하면 자동으로 사전 편찬 순에 따라 오름차순으로 정렬

 

 

 

 

 

 

Map인터페이스

 

Map 인터페이스는 (key) (value)으로 구성된 객체(Entry) 저장하는 구조

 

HashMap

(신버전,동기화x)

 

List나 set은 add로 저장하듯이 hashmap은 put으로 저장!!!!

 

HashMap은 해시 함수를 통해 '키'와 '값'이 저장되는 위치를 결정하므로, 사용자는 그 위치를 알 수 없고, 삽입되는 순서와 위치 또한 관계가 없다. 해싱(Hashing)을 사용하여 많은 양의 데이터를 검색하는 데 있어서 뛰어나다.

 

HashMap의 개별 요소가 되는 Entry 객체는 Map 인터페이스의 내부 인터페이스인 Entry 인터페이스를 구현하며, Map.Entry 인터페이스 안에도 메서드가 정의되어 있다.

 

주의할 점

Map은 키와 값을 쌍으로 저장하기 때문에 iterator()를 직접 호출할 수 없어 keySet() 이나 entrySet() 메서드를 이용해 Set 형태로 반환된 컬렉션에 iterator()를 호출하여 반복자를 만든 후, 반복자를 통해 순회하여야 한다!

// HashMap 생성
HashMap<String, Integer> map = new HashMap<>();


// Entry 객체를 요소로 가지는 Set을 생성 -> 아래에서 순회하기 위해 필요 
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();

 // entrySet을 순회하면서 value를 읽어옴 
Iterator<Map.Entry<String, Integer>> entryIterator = entrySet.iterator();
while(entryIterator.hasNext()) {
Map.Entry<String, Integer> entry = entryIterator.next();
String key = entry.getKey(); // Map.Entry 인터페이스의 메서드
Integer value = entry.getValue(); // Map.Entry 인터페이스의 메서드
System.out.println(key + " : " + value);
}

 

 

 

hashing이란

해시함수에 key값을 넣으면, index, 즉 저장위치(hashcode)를 알려줌    

해시함수를 이용하여 저장하고 읽어오는 것이 해싱이다.

Object.hash()를 이용하여 오버라이딩

 

해시테이블에 저장된 데이터를 가져오는 과정

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

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

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

 

서로다른 키여도 같은 값의 해시코드를 반환할 수 있다. (같은 data[index]에 저장되어 있는 경우)

 

 

 

hashmap에서 keyset는 꼭 반환타입이 set

why?중복이 불가능하므로

 

 

valuecollection에 저장

why?중복이 가능하므로

 

 

 

HashTable

(배열 + 링크드리스트 )

treeMAp(treeSet과 같은 구조)

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

Hashmap보다 데이터 추가 삭제에 시간이 더 걸림

 

 

 

 

 

 

📌문제풀이

코플릿 18번 getoddvalues

 

 

keySet으로 풀기

for(Character key : hashMAp.keySet)

각각의 hashMap 돌면서 KeySetKey에 저장 (KeySet으로 만듦)

//keySet

int sum = 0;
for (Character key: hashMap.keySet()){
	Integer value = hashMap.get(key);
    if (value& 2 == 0 ) sum += value;
}

	return sum;

 

 

Values으로 풀기

//values

Collection<Integer> values = hashMap.values();

Iterator<Integer> it = values.iterator();

whlie(it.hashNext()){
	Integer num = it.next();
    if(num%2 ==0) sum += num;
   }
   retrun sum;

Values는 컬렉션으로 받아야 함!(중복 가능하니까)((Value)요소는 인티저 타입)

Collection<Integer> values = hashMap.values();
Iterator<integer> it = values.iterator();
While(it.hasNext()){
	Ineteger num = it.next();

**Int num = it.next();

이렇게 하면 it.next는 엔트리 타입이고 num변수는 int타입이기에 넣을 수 없다.

 => Value값만 뽑아와줘야 함

 => Value값만 뽑는 메서드: getValue(그냥 get와 다름)

 

 

 

 

 

entryset으로 풀기

//entrySet

Set<Map.Entry<Character, Integer>> entrySet = hashMap.entrySet();

Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();

whilie(ir.hashNext()){
	int num = itnext{}.getVAlue{};
    if (num%2==0) sum +=num;
    }
    
    return sum;

 

return타입이 set이므로 set을 앞에 써주고 <타입지정(각 엔트리 객체)>

 

근데 각 엔트리 객체 타입은 Map에 저장되어있는 Entry타입임.

=>Map.Entry 인터페이스를 통해 접근!!!

Map.Entry<객체타입>

 

합치면

Set<Map.Entry<Character,Integor>>

 



학습 후 느낀점👀

 

구조를 그려 이해하기!

이번 개념도 여러 자료구조들의 특성들이 마구 들어와 헷갈렸지만 (특히 linkedList와 arrayList의 저장개념)

차근히 구조를 그림으로 그려보며 이해하였고, linkedList의 자료 추가 삭제가 왜 빠른지 정확하게 이해할 수 있었다.

 

실전이 중요하다

문제를 풀며 항상 느끼는 것인데 개념의 확립과 직접 코드를 작성하여 문제를 푸는 실전의 영역은 약간 다른 것 같다.

물론 개념이 정확히 확립되어야 문제를 더 잘 풀 수 있겠지만

개념만의 이해보단 직접 해봐야 확실히 활용할 수 있다는 것을 문제풀며 체감한다.

 

블로깅의 순기능

또 Map의 Entry 인터페이스에 대한 이해가 부족했는데 블로깅을 하며 정리하는 과정에서 확실히 이해했다

블로깅을 하면 누군가가 이것을 읽었을때 어떻게 하면 이해할 수 있을까를 생각하며 정리하게 되고

내 스스로에게 다시한번 설명해주는 느낌으로 설명과 이해를 반복한다.

그래서 개념 확립하기는 참 좋은 방법인듯 하다.

 

'Java' 카테고리의 다른 글

Java - 많이 쓰는 메소드 정리1 (배열 복사)  (0) 2022.09.23
Java - 배열 - > ArrayList변환하기  (1) 2022.09.23
Java - 람다와 메서드 참조  (0) 2022.09.18
Java-삼항연산자  (0) 2022.09.17
Java - 다형성  (0) 2022.09.17
복사했습니다!