Practice JAVA - Collections

최정환·2022년 12월 16일
0

Practice JAVA

목록 보기
9/10

자바는 잘 알려져있는 자료 구조를 사용해 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 인터페이스와 구현 클래스를 패키지에서 제공한다.

List

List는 배열과 비슷하게 객체를 인덱스로 관리한다.
배열과의 차이점은 저장 용량 자동 증가, 객체 저장시 인덱스 자동 부여다.

List는 객체 자체를 저장하는 것이 아니라 객체의 주소를 참조한다.
그렇기 때문에 동일한 객체를 중복 저장할 수 있고 이 때 동일한 주소가 참조된다.
null 저장 가능하며 이 때는 해당 인덱스는 객체를 참조하지 않는다.

기능메소드설명
객체 추가boolean add(E e)주어진 객체를 맨 끝에 추가
void add(int index, E e)주어진 인덱스에 객체를 추가
E set(int index, E e)주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈
객체 검색boolean contains(Object o)주어진 객체가 저장되어 있는지
E get(int index)인덱스에 저장된 객체 리턴
boolean isEmpty()컬렉션이 비어있는지
int size()저장되어 있는 전체 객체 수 리턴
객체 삭제void clear()저장된 모든 객체 삭제
E remove(int index)인덱스에 저장된 객체 삭제
boolean remove(Object o)주어진 객체 삭제

ArrayList

특징

  1. 생성하면 내부에 10개의 객체를 저장할 수 있는 초기 용량을 가지게된다.

  2. 저장되는 객체 수가 늘어나면 용량이 자동으로 증가한다.

  3. 객체 추가시 0번 부터 차례로 저장되고 제거시 바로 뒤 인덱스부터 마지막 인덱스까지 1씩 밀린다.

List<String> list = new ArrayList<String>();

void ListMethod(){
        // add
        list.add("value added");
        list.add(1,"third value" );
        // remove index 지정
        list.remove(0);

        System.out.println("list content = "+list + "list size" +list.size() + "index 0 value is : " + list.get(0));
    }

Vector

ArrayList와 동일한 내부 구조를 가지고 있다.

특징

동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Vector의 메소드들을 실행할 수 없고 하나의 스레드가 메소드 실행을 완료해야만 다른 스레드가 메소드를 실행할 수 있다.

따라서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제 가능하기때문에 스레드에 안전하다

    List<String> vector = new Vector<String>();

    void VectorMethod(){
        vector.add("Vector added");
        vector.add("Vector added2");
        vector.remove(1);
    }

LinkedList

인접 참조를 링크해서 체인처럼 관리한다.

특정 인덱스의 객체를 제거하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않는다.

따라서 ArrayList보다 특정 인덱스에서 추가/삭제를 할때 더 빠르다.

 List<Integer> linkedList = new LinkedList<Integer>();

Set

Set은 저장 순서가 유지되지 않는다.
객체를 중복해서 저장할 수 없고 하나의 null만 저장할 수 있다.

기능메소드설명
객체 추가boolean add(E e)객체 저장, 성공적 저장 true or false
객체 검색boolean contains(Object o)객체가 저장되어 있는지
boolean isEmpty()컬렉션이 비어있는지
Iterator<> iterator()저장된 객체를 한 번씩 가져오는 반복자
int size()저장되어 있는 전체 객체 수 리턴
객체 삭제void clear()저장된 모든 객체 삭제
boolean remove(Object o)주어진 객체 삭제

HashSet

객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다.

이때 동일한 객체는 꼭 같은 인스턴스만 뜻하는게 아니다.
HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode() 로 해시코드를 얻어내 이미 저장되어 있는 개체들의 해시코드와 비교한다.
만약 동일한 해시코드가 있다면 equals()로 두 객체를 비교해 true가 나온다면 저장하지 않는다.

Set<String> stringSet = new HashSet<String>();
    // 반복자 생성
    Iterator<String> HashSetIterator = stringSet.iterator();
    void hashSetMethod(){
        addValue(stringSet);
        loopSet(stringSet);
    }

    void addValue(Set<String> set){
        set.add("Java");
        set.add("Set");
        set.add("Map");
        set.add("List");
        System.out.println("SET CONTENT : "+set);
    }

    void loopSet(Set<String> set){
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            String element = iterator.next();
            System.out.println("\t" + element+"\t hashcode : "+element.hashCode());
        }
    }

Map

Map은 key(객체)-value(객체)로 구성된 Map.Enrty 객체를 저장하는 구조

Enrty는 Map 인터페이스 내부에 선언된 중첩 인터페이스다.

키는 중복 저장될 수 없지만 값은 중복 저장될 수 있다.
만약 중복된 키로 다른 값을 저장하면 해당 키로 새로운 값이 업데이트된다.

기능메소드설명
객체 추가V put(K key, V value)key-value로 저장
객체 검색boolean containsKey(Object key)키가 있는지 확인
boolean containsValue(Object value)값이 있는지 확인
Set<Map.Entry<K,V>> enrtySet()키와 값의 쌍으로 구성된 모든 Map.Enrty객체를 Set에 담아 리턴
V get(Object key)key에 대한 값
boolean isEmpty()컬렉션 비어 있는지
Set<K> keySet()모든 키 Set에 담아 리턴
int size()키의 총 수
Collection<V> values()저장된 모든 값을 Collection에 담안 리턴
객체 삭제void clear()모든 Map.Enrty 삭제
V remove(Object key)주어진 키와 일치하는 Map.Entry 삭제 후 값 리턴

HashMap

key로 사용할 객체는 hashCode(), equals() 메소드를 재정의해 동등 객체가 될 조건을 정해야한다.
객체가 달라도 동등 객체라면 같은 key로 간주하고 중복 저장되지 않도록하기 위함이다.

 Map<String, Integer> hashmap = new HashMap<String, Integer>();

    void HashMap(){
        // craete Map.Entry
        hashmap.put("철수",90);
        hashmap.put("영수",81);
        hashmap.put("김수",30);
        hashmap.put("가수",10);

        System.out.println("Map의 size는 "+hashmap.size()+"\t 철수의 점수는 "+ hashmap.get("철수"));

        // Set으로 key-value 얻기
        Set<String> keySet = hashmap.keySet();
        Iterator<String> iterator = keySet.iterator();

        while (iterator.hasNext()){
            String key = iterator.next();
            Integer value = hashmap.get(key);
            System.out.println("key : "+key+"\t value : "+value);
        }
        
        // 가수 제거
        hashmap.remove("가수");

HashTable

List의 Vector와 같이 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Hashtable의 메소드를 실행할 수 없고 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행할 수 있다.

따라서 스레드에 안전하다.

Map<String, String> hashtable = new Hashtable<String, String>();
    
    void HashTable(){
        // id, password를 map으로 저장
        hashtable.put("봄", "12");
        hashtable.put("여름", "123");
        hashtable.put("가을", "1234");
        hashtable.put("겨울", "12345");
        
        // 내용 입력받기 위해 스캐너 사용
        Scanner scanner = new Scanner(System.in);
        
        while (true){
            System.out.println("아이디와 비번 입력하세요");
            System.out.println("아이디 : ");
            String id = scanner.nextLine();
            System.out.println("비밀번호  : ");
            String password = scanner.nextLine();
            System.out.println();
            
            if(hashtable.containsKey(id)){
                if(hashtable.get(id).equals(password)){
                    System.out.println("로그인 완료");
                    break;
                }else{
                    System.out.println("비밀번호가 다릅니다.");
                }
            }else{
                System.out.println("아이디가 존재하지 않습니다.");
            }
        }
        

Stack (LIFO)

LIFO 자료구조를 구현한 클래스

리턴 타입메소드설명
Epush(E item)객체를 스택에 넣음
Epeek()스택의 맨 위 객체를 가져옴
Epop()스택의 맨 위 객체를 가져옴 이 객체를 스택에서 삭제함
class StackCollection{
     class Coin{
         private int value;
         Coin(int value){this.value = value;}
         int getValue(){
             return value;
         }
     }


     Stack<Coin> CoinBox = new Stack<Coin>();
     void CoinBoxPush(){
         CoinBox.push(new Coin(100));
         CoinBox.push(new Coin(300));
         CoinBox.push(new Coin(200));
         CoinBox.push(new Coin(600));
     }

     void getLastCoin(){
         System.out.println(CoinBox.peek());
     }

     void CoinBoxPopAll(){
         while (!CoinBox.isEmpty()){
             CoinBox.pop();
         }
     }
}

Queue (FIFO)

FIFO 자료구조를 구현한 클래스

Queue 인터페이스를 구현한 대표적인 클래스는 LinkedList

리턴 타입메소드설명
booleanoffer(E item)객체를 큐에 넣음
Epeek()큐 맨 밑 객체를 가져옴
Epoll()큐의 맨 밑 객체를 가져옴 이 객체를 큐에서 삭제함
class QueueCollection{
    
    class Message{
        String command;
        String to;
        Message(String command, String to){
            this.command = command;
            this.to = to;
        }
    }
    Queue<Message> queue = new LinkedList<>();
    
    void offerQueue(){
        queue.offer(new Message("메일 보내기","철수"));
        queue.offer(new Message("문자 보내기","지수"));
        queue.offer(new Message("카톡 보내기","가수"));
    }
    
    void pollAll(){
        while (!queue.isEmpty()){
            Message msg = queue.poll();
            switch (msg.command){
                case "메일 보내기":{
                    System.out.println(msg.to+"에게 "+msg.command);
                }case "문자 보내기":{
                    System.out.println(msg.to+"에게 "+msg.command);
                }case "카톡 보내기":{
                    System.out.println(msg.to+"에게 "+msg.command);
                }
            }
        }
    }
    
    
}

0개의 댓글