코드스테이츠 백엔드 부트캠프 16일차 [컬렉션(Collection)-Quiz]

wish17·2023년 1월 5일
0
post-thumbnail

단답형 퀴즈

  • 컬렉션 프레임워크는 자주 사용되는 자료구조를 편리하게 사용할 수 있도록, 자료구조 및 관련된 메서드들을 미리 구현해둔 것이다.
    o

  • 컬렉션 프레임워크의 인터페이스로는 List, Set, Map 등이 있으며, 모두 Collection 인터페이스를 상속받는다.
    x

  • 모든 컬렉션 클래스들에는 기본 타입도 저장할 수 있다.
    x

  • List 인터페이스를 구현한 컬렉션 클래스들은 데이터의 저장 순서를 유지하며, 중복 저장을 허용한다.
    o

  • ArrayList는 배열과 달리 크기를 초과하여 요소를 추가하면 자동으로 크기가 늘어난다.
    o

  • ArrayList는 요소를 검색할 때 좋은 성능을 보이지만, 순차적으로 요소를 추가하거나 삭제할 때에는 그렇지 않다.
    x

  • LinkedList는 요소를 검색할 때에는 상대적으로 좋은 성능을 보이지 못하지만, 중간에 위치한 요소를 추가하거나 삭제할 때 ArrayList보다 효율적으로 동작한다.
    o

  • ArrayList와 LinkedList 모두, 내부적으로 객체의 참조값들이 서로 인접하여 메모리 공간 상에 위치하게 된다.
    x

  • String 타입의 요소를 저장하고 있는 ArrayList al의 이터레이터를 생성하여 참조 변수 it 에 할당하는 코드는?
    Iterator<String> it = al.iterator();

  • Set은 List와 달리 데이터의 중복 저장을 허용하지 않으며, 데이터의 저장 순서를 유지하지 않는다.
    o

  • HashSet에 데이터를 저장하면 자동으로 정렬된다.
    x (기본적으로 사전 편찬순서로 정렬된다. 정렬방법 심화학습 원하면 Comparator Comparable검색)

  • HashSet은 hashCode() 메서드와 equals() 메서드로 데이터의 중복을 검사하며, 이 두 메서드는 오버라이딩하여 재정의할 수 있다.
    o

  • TreeSet은 이진탐색트리의 구조로 데이터를 저장하는 컬렉션으로, 입력 데이터를 자동으로 정렬해준다.
    o

  • 이진탐색트리의 부모노드는 자식노드보다 큰 값을 가진다.
    x (왼쪽은 작은값 오른쪽 자식은 더 큰 값을 갖는다. 즉,부모는 중간값)

  • Map은 Key 객체와 Value 객체를 합친 Entry 객체의 형태로 데이터를 저장하며, 이 때 Key와 Value는 모두 중복 저장이 허용된다.
    x (key는 중복저장 x)

  • HashMap은 Key 객체를 해싱하여 메모리 주소를 얻으며, 해당 메모리 주소에 Value 객체가 저장된다.
    o

  • HashMap을 순회하려면 바로 iterator 메서드를 호출하면 된다.
    x (일단 set으로 바꾼다음 호출 해야한다)

  • hashMap의 Key가 Integer타입이고, Value가 Boolean 타입일 때, 아래 빈칸에 들어갈 코드는?
    ___________________ = hashMap.entrySet();
    답: Set<Map.Entry<Integer, Boolean>> entrySet

  • hashMap의 Key만 가져오는 메서드 keySet은 Key 객체의 값을 Set에 담아준다. 그 이유는 무엇인가?
    답: set은 중복을 허용하지 않기 때문

  • hashMap의 Value만 가져오는 메서드 values는 반환 타입이 Set이 아닌 Collection 타입이다. 그 이유는 무엇인가?
    답: 중복 허용하기 때문

질문: 데이터를 순차적으로 처리하기 위해서 Arraylist가 아닌 Iterator를 사용하는 이유가 Map형태거나 객체 중복이 허용되지 않는 등의 컬렉션에 적용하기 위함일까요?

답변: Arraylist는 자료구조다. 이터레이터는 자료구조에서 값을 순회하기 위한 메서드인거다.
(set,map같은 자료구조들을 Arraylist로 바꿔서 순회하는게 편하지 않나 생각한거였는데 애초에 다른 특성을 필요로한 자료구조이니
질문부터 틀린 것 같다.)

코딩Quiz

2번

Integer 타입의 ArrayList와 수를 입력받아 수가 인덱스로 가리키는 ArrayList의 요소를 리턴하라.

  • 빈 ArrayList를 입력받은 경우, null을 리턴해야 한다.
  • ArrayList의 크기를 벗어나는 인덱스를 입력받은 경우, null을 리턴해야 한다.

나의 코드

import java.util.*;

public class Solution { 
  public Integer getNthElement(ArrayList<Integer> arrayList, int index) {
    
    if (arrayList.size() == 0) return null;
    else {
      return arrayList.get(index);      
    }
  }
}

삼항연산자 잘쓰자~

ans

import java.util.*;

public class Solution { 
  public Integer getNthElement(ArrayList<Integer> arrayList, int index) {

    return arrayList.size() == 0 || index >= arrayList.size() ? null : arrayList.get(index);

  }
}

10번

String 타입을 요소로 가지는 배열을 입력받아, String 타입을 요소로 가지는 ArrayList로 변환하여 리턴하라.

  • 빈 배열의 경우 null을 리턴해야 한다.

나의 풀이

import java.util.*;

public class Solution { 
  public List<String> arrayToArrayList(String[] arr) {
  
    ArrayList<String> newList = new ArrayList<String>(Arrays.asList(arr)); 

    if (arr.length ==0) return null;
    return newList;    
  }
}

배열의 요소와 같은 객체로 구성 된 ArrayList 만들어주는 Arrays.asList(arr) 활용

ans

import java.util.*;

public class Solution { 
  public List<String> arrayToArrayList(String[] arr) {

    if (arr.length ==0) return null;
    else return new ArrayList(Arrays.asList(arr)); //추가
    
  }
}

18번

<Character, Integer> 타입을 요소로 가지는 HashMap을 입력받아 짝수 값(Value) 끼리 모두 더한 값을 리턴하라.

<리마인드>

  • hashMap.entrySet() hashMap의 모든 entry 객체 전체(key와 value)를 Set 객체에 담아서 리턴.
  • hashMap.keySet() hashMap의 모든 키를 Set 객체에 담아서 리턴
  • hashMap.valueSet() hashMap의 모든 값(value)을 Set 객체에 담아서 리턴

나의 풀이1

import java.util.*;

public class Solution { 
  public int addOddValues(HashMap<Character, Integer> hashMap) {

    int result = 0;
    for(Character key : hashMap.keySet()) {
      if(hashMap.get(key)%2==0){
        result = result+hashMap.get(key);
      }
    }
    return result;

hash 자체로는 순회할 수 없어 key 모음(keySet)을 이용해 for문으로 순회해 값(Value)들의 짝수 여부를 판단했다.

나의 풀이2

import java.util.*;

public class Solution { 
  public int addOddValues(HashMap<Character, Integer> hashMap) {

    Set<Character> key = hashMap.keySet(); // hashMap의 모든 키를 Set 객체에 담아서 리턴

    Iterator<Character> ik = key.iterator(); // keySet을 Itrtator 타입의 인스턴스로 리턴
    int result = 0;

    while (ik.hasNext()) {
      if(hashMap.get(ik.next())%2==0){
        result += hashMap.get(ik.next());
      }
    }
    return result;
  }
}

이게 왜 안되는거지???
디버깅을 통해 알아보니 짝수번째 key만 if(true)가 된다...

import java.util.*;

public class Solution { 
  public int addOddValues(HashMap<Character, Integer> hashMap) {

    Set<Character> key = hashMap.keySet(); // hashMap의 모든 키를 Set 객체에 담아서 리턴

    Iterator<Character> ik = key.iterator(); // keySet을 Itrtator 타입의 인스턴스로 리턴
    int result = 0;

    while (ik.hasNext()) {
      int val = hashMap.get(ik.next());
      if(val%2==0){
        result += val;
      }
    }
    return result;
  }
}

근데 또 이렇게 하면 되네??..

나의 풀이3

import java.util.*;

public class Solution { 
  public int addOddValues(HashMap<Character, Integer> hashMap) {

    Collection<Integer> values = hashMap.values(); // hashMap의 모든 키를 Set 객체에 담아서 리턴

    Iterator<Integer> ik = values.iterator(); // keySet을 Itrtator 타입의 인스턴스로 리턴
    int result = 0;

    while (ik.hasNext()) {
      int val =ik.next();
      if(val%2==0){
        result += val;
      }
    }
    return result;
  }
}

나의 풀이4

import java.util.*;

public class Solution { 
  public int addOddValues(HashMap<Character, Integer> hashMap) {

    Set<Map.Entry<Character,Integer>> entrySet = hashMap.entrySet(); // hashMap의 모든 키를 Set 객체에 담아서 리턴

    Iterator<Map.Entry<Character,Integer>> ik = entrySet.iterator(); // keySet을 Itrtator 타입의 인스턴스로 리턴
    int result = 0;

    while (ik.hasNext()) {
      int val =ik.next().getValue();
      if(val%2==0){
        result += val;
      }
    }
    return result;
  }
}

3,4번 풀이도 2번째 풀이와 같은 문제를 겪었다.
val이라는 변수를 통해 할당해야지만 의도한데로 수행한다.

문제 해결
next()는 while과 별개로 호출될 때 마다 다음 값을 가져온다.
따라서 if 조건문 안에서 선언한 next()와 실행문 안에서 선안한 next는 다른 값을 호출하는 것이다.


24번

문자열을 입력받아 문자열을 구성하는 각 문자(letter)를 키로 갖는 HashMap을 리턴해야 한다.
각 키의 값은 해당 문자가 문자열에서 등장하는 횟수를 의미하는 int 타입의 값이어야 한다.

  • 빈 문자열을 입력받은 경우, null을 리턴하라.

나의 풀이

import java.util.*;

public class Solution { 
  public HashMap<Character, Integer> countAllCharacter(String str) {
    char[] arr = str.toCharArray();
    HashMap<Character,Integer> result = new HashMap<>();
    
    if(arr.length==0) {
      return null;
    }else {
      for(int i=0; i<arr.length; i++) {
         int value = 0;
        for (int j=0; j<arr.length; j++) {
          boolean up = false;
          
          if(arr[i]==arr[j]){
            if (i<j) break; // 아래 첨언
            else up = true;
          }
          if(up==true) value++;
        }
        result.put(arr[i],value);
      }
    return result;
    }
  }
}

i>j로 하면 진행되다 break에 도달하기 전에 값이 덮어져버린다. 그래서 맨 마지막 문자 기준으로 똑같은 문자가 몇개인지 카운트 하고, value가 계산될 수 있도록 i<j로 했다.

ans

import java.util.*;

public class Solution { 
  public HashMap<Character, Integer> countAllCharacter(String str) {
    if (str.isEmpty()) {
      return null;
    }
    HashMap<Character, Integer> hashMap = new HashMap<>();
    for (int i = 0; i < str.length(); i++) {
      char curChar = str.charAt(i);
      if (hashMap.containsKey(curChar)) {
        int value = hashMap.get(curChar);
        hashMap.put(curChar, value + 1);
      } else {
        hashMap.put(curChar, 1);
      }
    }
    return hashMap;
  }
}

hashMap 메서드를 활용해 더 간단하게 풀 수 있다.
주말쯤 다시 해보자.

정리

  • 메서드는 원리만 그때그때 이해하고 찾아서 쓰자. (암기x)

  • 각 메서드의 출력 타입이 뭔지 잘생각하자.

    • return arrayList.add(str);의 경우 add에 성공or실패로 boolean타입의 출력이 나온다.
  • 메서드 특성을 잘 확인하고 쓰자.

    • arrayList.set(index,element) 주어진 index 위치의 요소값을 없애고 element를 넣는거
    • arrayList.add(index,element) 주어진 index 위치에 element를 넣고 기존에 있던애를 뒤로 한칸 미루는거

0개의 댓글