컬렉션 프레임워크

2022. 12. 11. 03:46자바

728x90

여러가지 컬렉션을 제공하는 자바 라이브러리

-java.util 패키지에 정의되어 있음

*컬렉션? 데이터를 한곳에 모아 저장 및 관리하는 가변 크기의 오브젝트 컨테이너

 

<컬렉션 프레임워크 구조>

제네릭으로 여러 타입과 호환되게 구성한 인터페이스와 

그 인터페이스를 구현한 클래스로 구성되어 있다.

*링크드리스트는 리스트의 자식이기도 하고 큐의 자식이기도 하다

 

<collection 인터페이스>

interface Collection<E>  //제네릭 타입 E가 컬렉션의 원소 타입 지정

dafault void forEach(Consumer<? super T> action)

//모든 원소에 대해 action 수행, action에 인자로 람다 표현식을 전달

 

default boolean removeIF(Predicate <? super E> filter)

//filter의 결과 true이면 원소 삭제

 

<List 인터페이스>

static <E> List<E> of (E... elements) //인자가 여러개 올수 있다.

-리스트로 만들어서 반환하는 함수

-인자를 불변 리스트로 반환(원소를 추가하거나 삭제할 수 없다)

-null 값을 원소로 가질 수 없음

-원소를 10개 이하로 사용하도록 오버로딩 되어 있음

 

public static <T> List<T> asList(T...a)

-배열을 리스트로 변환하는 메서드 (Array에 정의)

-크기가 고정되어 있어 수정은 가능하나 추가는 불가

 

<T> T[] toArray(T[] a)

- 리스트를 배열로 변환하는 메서드(List에 정의)

 

 String[] animals1 = { "Deer", "Tiger", "Seal", "Bear" };
 List<String> animals2 = Arrays.asList(animals1); //리스트로 변환
 animals2.set(1, "Parrot"); //of 메서드로 변환한게 아니라 set메서드로 원소 교체는 가능
 animals2.add(0, "Wolf"); //런타임에러 발생-> 원소 추가는 불가

 

 String[] animals3 = animals2.toArray(new String[0]);
 //리스트를 배열로 변환

*인자를 size를 0으로 명시해서 생성한 이유?

 List의 size > 인자로 넘어가는 배열 객체의 size -> 해당 List의 size로 배열이 만들어진다.

반대로 List의 size < 인자로 넘어가는 배열객체의 size -> 인자로 넘어가는 배열객체의 size로 배열이 만들어진다.

 

List<String> car = List.of("Grandeur", "Sonata","Avante", "Genesis"); //of메서드로 리스트 생성
 car.set(1, "Santa Fe"); //원소 교체 불가
 List<Object> objects = List.of("a", null); //널값으로 리스트 생성 불가

<Iterator 인터페이스>

컬렉션 원소에 접근하기 위한 반복자

*키-값 구조의 Map 컬렉션은 반복자 미제공

Collection<String> list = Arrays.asList("A", "B", "C"); 
//컬렉션 인터페이스는 리스트의 부모이니깐 리스트 받을 수 있다.
Iterator<String> iterator = list.iterator();//리스트의 첫번째 원소 바로 앞을 가리키고 있음(빈 공간)
while (iterator.hasNext())//hasNext(): 다음 원소의 존재 여부를 반환
	System.out.print(iterator.next() + ",");//next(): 다음 원소를 반환
System.out.println();

여기서 한번 더  while문을 실행한다면?

while (iterator.hasNext())
	System.out.print(iterator.next() + ",");
System.out.println();

반복자가 마지막 인덱스 다음을 가리키는 상태이다.

따라서 다음 원소가 없으므로 while문이 실행되지 않는다.

iterator = list.iterator();
while (iterator.hasNext())
	System.out.print(iterator.next() + ",");
System.out.println();

위와 같이 반복자를 다시 할당한다면 반복문 가능


<ArrayList 클래스>

가변 크기의 동적 배열

Vector 클래스와 하는 일은 유사하지만 동기화된 메서드로 구현되어 있다

-> 즉, vector클래스는 syncronized 메서드(스레드가 접근중이면 다른 스레드는 접근 불가)로 구현되어 있기 때문에

멀티스레드 환경에서 안전하다.

 

*가변 배열의 장점

List<String> list = List.of("Grandeur", "Sonata","Avante", "Genesis", "Soul");
//불변리스트로 생성
List<String> cars1 = new ArrayList<>(list);
//불변리스트를 인자로 받아서 ArrayList 생성하면 이제 가변
cars1.add("Santa Fe"); // 원소 추가 가능
cars1.removeIf(c -> c.startsWith("So")); //원소 삭제 가능(So로 시작하는 원소 삭제하는 람다식)
cars1.replaceAll(s -> "New " + s); //원소 교체 가능(모든 원소 앞에 New 붙히는 람다식)
cars1.forEach(s -> System.out.print(s + " ")); //모든 원소를 출력
System.out.println();
cars1.clear(); //모든 원소 삭제

<Stack 클래스>

-Vector의 자식 클래스

-인덱스가 1부터 시작하는 것이 특징(탑이 인덱스 1번)

Stack<String> s1 = new Stack<>(); //String 타입의 빈 스택 생성
s1.push("Apple");
s1.push("Banana");
s1.push("Cherry");
System.out.println(s1.peek());// 탑을 엿봄->Cherry 출력
Stack<Integer> s2 = new Stack<>(); //Integer 타입의 빈 스택 생성
s2.add(10);
s2.add(20);
s2.add(1, 100);//1번 인덱스 다음에 원소 100 추가
for (int value : s2) //for each문을 쓰면 리스트로 보고 접근해서 바텀부터 출력
	System.out.print(value + " "); //10 100 20
System.out.println();

* for each문을 쓰면 리스트로 보고 접근해서 바텀부터 출력


<LinkedList 클래스>

ArrayList 클래스와의 차이

-특정 원소 값을 얻어오는 건 배열이 빠름(링크드리스트는 처음부터 순회해야하니깐)

-원소 추가/제거는 링크드리스트가 빠름(전후 원소의 참조값만 조정하면 되니깐)

-링크드리스트가 앞뒤 포인터가 있어야하기 때문에 아무래도 메모리 소모가 더 크다

-링크드리스트는 순방향 뿐만 아니라 역방향 반복자도 지원

 

*System.nanoTime(); // 작동중인 JVM의  현재 시간을 long타입인 나노세컨드단위(10억분의 1초) 반환

프로그램의 성능 측정을 위해 나노초로 정밀하게 구간 시간 측정을 위해 사용


<Queue 인터페이스>

-큐의 중간에 원소를 추가하거나 제거할 수 없음

-head에서 제거, tail에 추가

 

*큐의 메서드들 

왼쪽 메서드들은 예외처리를 해줘야 사용 가능

Queue<String> q = new LinkedList<>();

링크드리스트를 큐로 생성 // 링크드리스트가 자식이라 가능

q.remove(); //예외처리 안해줘서 사용 불가
System.out.println(q.poll()); //빈 큐이기 때문에 null 출력
q.offer("Apple"); //원소 삽입
System.out.println("Did you add Banana? " + q.offer("Banana")); 
//바나나를 추가했으므로 Did you add Banana? true 출력
try {
            q.add("Cherry"); //예외처리 해줘서 사용 가능
        } catch (IllegalStateException e) {//add()에 대한 예외처리
        }

        System.out.println("Head: " + q.peek()); //헤드는 제일 먼저 추가한 Apple
        String head = null;
        try {
            head = q.remove(); //헤드가 제거-> head=Apple;
            System.out.println(head + " removed");
            System.out.println("New head: " + q.element());//새로운 헤드 Banana 출력
            //element(),peek(): 헤드 원소를 반환
        } catch (NoSuchElementException e) {//remove(), element()에 대한 예외처리
        }
        head = q.poll();//헤드 제거->head=banana;
        System.out.println(head + " removed");
        System.out.println("New head: " + q.peek());//새로운 헤드 Cherry 출력

<Set 인터페이스>

순서가 없으며, 중복되지 않는 오브젝트를 저장하는 자료구조

-인덱스가 없어서 저장 순서 무시

-중복 원소 배제

* 같은 오브젝트 구별: 

hashCode()의 반환값이 같고 equeals()의 반환값이 true인 오브젝트들

*HashSet: 해싱을 이용한 구현체

탐색 속도가 빠름

*TreeSet: 이진탐색트리를 이용한 구현체

데이터 정렬이 가능함

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

class HashSetDemo {
    public static void main(String[] args) {
        String[] fruits = { "Apple", "Banana","Grape", "Watermelon" };
        Set<String> h1 = new HashSet<>();
        Set<String> h2 = new HashSet<>();
        for (String s : fruits)
            h1.add(s);// h1에 fruits 원소들을 모두 추가
        h1.add("Banana"); // 중복되서 추가 안됨
        h1.remove("Grape");
        h1.add(null); // null 허용
        System.out.println(h1);// [null, Apple, Watermelon, Banana]
        System.out.println(h1.contains("Watermelon"));//해당 문자열이 있는지 확인->있으면 true
        List<String> list = Arrays.asList(fruits);//배열을 리스트로 변환
        h2.addAll(list);// h2에 list 원소들을 모두 추가
        System.out.println(h2);
    }
}

<Map 인터페이스>

키와 값의 쌍으로 구성된 오브젝트를 저장하는 자료구조

-키는 중복되지 않고 하나의 값에만 매핑되어 있음

 

*Map.Entry<K,V>의 메서드

-Map의 키.값을 조작할  때 사용

import java.util.HashMap;
import java.util.Map;

class HashMap1Demo {
    public static void main(String[] args) {
        Map<String, Integer> map = Map.of("Apple", 5, "Banana", 3, "Grape", 10, "Strawberry", 1);
        // of 메서드로 생성해서 불변 맵
        Map<String, Integer> fruits = new HashMap<>(map);
        // HashMap 생성자로 불변 맵을 전달해서 가변 맵 생성
        System.out.println("# of fruit types: " +fruits.size()); //4
        fruits.remove("Banana");// Banana 키를 가진 맵 요소 삭제
        System.out.println("# of fruit types: " +fruits.size());//3
        
        fruits.put("Mango", 2);// Mango 키를 가진 맵 요소 추가
        System.out.println("After adding Mango: " + fruits);
        // After adding Mango: {Mango=2, Apple=5, Grape=10, Strawberry=1}
        //순서는 랜덤
        fruits.clear();// 모든 맵 요소 삭제
        System.out.println("# of fruit types: " +fruits.size());//0
    }
}

<Collections 클래스>

컬렉션을 다루는 다양한 메서드 제공

- 원소 정렬, 섞기, 탐색 등

String[] fruits = { "Grape", "Watermelon","Apple", "Kiwi", "Mango" };
List<String> list = Arrays.asList(fruits);
Collections.sort(list,Collections.reverseOrder()); //list를 내림차순으로 정렬
Collections.reverse(list);//list의 순서를 역방향으로 뒤집는다

-기타 다른 메서드

728x90

'자바' 카테고리의 다른 글

ArrayList  (0) 2023.03.25
정적 배열 정리  (0) 2023.03.25
네트워크 프로그래밍  (0) 2022.12.10
네트워크 기본 용어  (0) 2022.12.10
람다 표현식  (2) 2022.12.10