GeehDev

[Java] 컬렉션 - 1) 컬렉션과 List(ArrayList, LinkedList, Vector) 본문

Study/Java

[Java] 컬렉션 - 1) 컬렉션과 List(ArrayList, LinkedList, Vector)

geehyun 2024. 9. 15. 16:32

Index

    반응형

    컬렉션의 경우 내용이 많아

    1. [Java] 컬렉션 - 1) 컬렉션과 List(ArrayList, LinkedList, Vector)
    2. [Java] 컬렉션 - 2) Set (HashSet, LinkedHashSet, TreeSet)
    3. [Java] 컬렉션 - 3) Set(HashMap, HashTable, LinkedHashMap, TreeMap) - 작성중

    의 3개의 시리즈로 구성됩니다.

     

    [Java] 컬렉션 - 1) 컬렉션과 List

    컬렉션컬렉션이란 동일한 타입을 묶어서 관리하는 자료구조를 말합니다.이렇게만 설명할 경우 굉장히 배열(Array)와 비슷해 보이는데,어느정도 비슷한 면은 있지만 가장 큰 차이점은 배열은 생

    geehyun.tistory.com

     

     

    [Java] 컬렉션 - 2) Set (HashSet, LinkedHashSet, TreeSet)

    컬렉션의 경우 내용이 많아 [Java] 컬렉션 - 1) 컬렉션과 List(ArrayList, LinkedList, Vector)[Java] 컬렉션 - 2) Set (HashSet, LinkedHashSet, TreeSet)[Java] 컬렉션 - 3) Set(HashMap, HashTable, LinkedHashMap, TreeMap)의 3개의 시리

    geehyun.tistory.com

     


     

    컬렉션

    컬렉션이란 동일한 타입을 묶어서 관리하는 자료구조를 말합니다.
    이렇게만 설명할 경우 굉장히 배열(Array)와 비슷해 보이는데,

    어느정도 비슷한 면은 있지만 가장 큰 차이점은 배열은 생성한 시점에 저장공간을 확정해야한다면, 컬렉션은 저장공간을 동적으로 관리할 수 있다는 점 입니다.

    컬렉션구조

    컬렉션의 경우 특성에 따라 구분한 List<E>, Set<E>, Map<K, V>과 기존 컬렉션 기능을 확장 또는 조합한 Stack<E>, Queue<E>가 있습니다.

     

    • List<E>
      Collection<E>를 상속받은 컬렉션 인터페이스로 원소를 인덱스로 관리한다는 점에서 배열과 가장 유사한 구조를 갖고 있습니다.
      해당 인터페이스를 구현한 구현 클래스로는 ArrayList<E>, Vector<E>, LinkedList<E>가 있습니다.
    • Set<E>
      Collection<E>를 상속받은 컬렉션 인터페이스로 원소 집합체라는 개념의 컬렉션으로, 인덱스의 개념이 없어 원소(데이터) 간의 중복을 허용하지 않는게 특징입니다.
      해당 인터페이스를 구현한 구현 클래스로는 HashSet<E>, LinkedHashSet<E>, TreeSet<E>이 있습니다.
    • Map<K, V>
      Key : value의 엔트리로 구성*
      되는 Map<K, V>은 구조상의 이유로 Collection<E>과 별도로 존재하는 인터페이스 입니다만, 컬렉션으로 분류됩니다.
      해당 인터페이스를 구현한 구현 클래스로는 HashMap<K, V>, LinkedHashMap<K, V>, HashTable<K, V>, TreeMap<K, V>이 있습니다.
    💡 TreeSet<E>TreeMap<K, V>
      • TreeSet<E>
        Set<E>을 상속받아 정렬기능을 추가한 SortedSet<E>인터페이스와 검색기능을 추가한 NavigableSet<E>인터페이스를 구현한 구현클래스 입니다.
      • TreeMap<K, V>
        Map<K, V>을 상속받아 정렬기능을 추가한 SortedMap<K, V>인터페이스를 상속받아 검색기능을 추가한 NavigableMap<K, V>인터페이스를 구현한 구현클래스 입니다.

        따라서 두 클래스 모두 추가된 정렬, 검색 기능을 사용하기 위해서는 객체를 생성할 때 Set<E>, Map<K, V>가 아닌 TreeSet<E>, TreeMap<K, V>을 자료형으로 객체를 생성해야합니다.

     

    • Stack<E>
      Vector<E>의 자식 클래스*
      로, LIFO(Last In First Out) 후입선출 자료구조를 구현한 클래스 입니다.
      다른 컬렉션들이 인터페이스로 작성되어 이를 구현한 구현클래스로 객체 생성을 해야하는 것과 다르게 자체적으로 객체 생성이 가능한 클래스 입니다!
    • Queue<E>
      Collection<E>를 상속받은 컬렉션 인터페이스로, FIFO(First In First Out) 선입선출 자료구조를 구현한 인터페이스 입니다.
      해당 인터페이스를 구현한 구현 클래스는 LinkedList<E> 입니다.

    💡 Collection 각 특성 요약

    Collection 각 특성 요약

    List

    배열과 가장 비슷한 구조를 가지고있는 자료구조 입니다.
    배열과의 차이점은, 저장공간을 동적으로 관리할 수 있다는 점에서 차이점이 있습니다.
    인덱스(순서)가 있는 데이터 리스트로, 순서로 구분하기 때문에 데이터간 중복을 허락합니다.

    ArrayList

    • 데이터를 인덱스로 관리합니다.
    • 저장공간을 동적으로 관리할 수 있습니다.
    • 객체 생성시 생성자(저장용량)로 지정해줄 수 있으며, 미지정 시 10으로 설정됩니다.
      //사용법
      ArrayList<제네릭 타입지정> 참조변수 = new ArryaList<제네릭 타입지정>();
      ArrayList<제네릭 타입지정> 참조변수 = new ArryaList<제네릭 타입지정>(사이즈);
      // 다형성에 따라 부모인터페이스인 List 타입으로 객체 생성가능
      List<제네릭 타입지정> 참조변수 = new ArryaList<제네릭 타입지정>();
      List<제네릭 타입지정> 참조변수 = new ArryaList<제네릭 타입지정>(사이즈);
      // 사용예시
      List<String> aList = new ArrayList<String>();
      aList.add("바보");    // add()로 리스트에 값 추가
      aList.add("멍청이");
      aList.add("말미잘"); 
      System.out.println(aList); // 출력 : [바보, 멍청이, 말미잘]

    Vector

    • 데이터를 인덱스로 관리합니다.
    • 저장공간을 동적으로 관리할 수 있습니다.
    • 객체 생성시 생성자(저장용량)으로 지정해줄 수 있으며, 미지정 시 10으로 설정됩니다.
    • 동기화 메서드(Synchronized method)로 구현되어있어 멀티쓰레드에 적합합니다.
      (싱글쓰레드에서는 ArrayList를 사용하는 것 이 효율적입니다.)
      //사용법
      Vector<제네릭 타입지정> 참조변수 = new Vector<제네릭 타입지정>();
      Vector<제네릭 타입지정> 참조변수 = new Vector<제네릭 타입지정>(사이즈);
      // 다형성에 따라 부모인터페이스인 List 타입으로 객체 생성가능
      List<제네릭 타입지정> 참조변수 = new Vector<제네릭 타입지정>();
      List<제네릭 타입지정> 참조변수 = new Vector<제네릭 타입지정>(사이즈);
      // 사용예시
      List<String> vList = new Vector<String>();
      vList.add("바보");    // add()로 리스트에 값 추가
      vList.add("멍청이");
      vList.add("말미잘"); 
      System.out.println(vList); // 출력 : [바보, 멍청이, 말미잘]

    LinkedList

    • 데이터간 앞뒤 원소의 정보를 저장하는 방식의 구조 입니다.
    • 인덱스를 사용할 수는 있지만 인덱스 정보를 저장하고있지않아 사용할 때마다 계산해야해서 검색 속도가 느립니다.
    • 데이터를 중간에 추가/삭제 시 추가한 데이터의 앞뒤 연결정보만 수정하면되서 속도가 빠릅니다.
    • 저장공간을 동적으로 관리할 수 있습니다.
    • 객체 생성시 생성자(저장용량)으로 지정할 수 없습니다.
      //사용법
      LinkedList<제네릭 타입지정> 참조변수 = new LinkedList<제네릭 타입지정>();
      // 다형성에 따라 부모인터페이스인 List 타입으로 객체 생성가능
      List<제네릭 타입지정> 참조변수 = new LinkedList<제네릭 타입지정>();
      // 사용예시
      List<String> lList = new LinkedList<String>();
      lList.add("바보");    // add()로 리스트에 값 추가
      lList.add("멍청이");
      lList.add("말미잘"); 
      System.out.println(lList); // 출력 : [바보, 멍청이, 말미잘]

    💡 ArrayList vs LinkedList


    구분 ArrayList LinkedList
    저장방식 데이터에 인덱스를 저장하여 관리| 각 원소간 앞뒤 원소의 정보를 저장하여 관리
    추가(add), 삭제(remove) 느림 🐢 빠름 🐇
    검색(get) 빠름 🐇 느림 🐢
    • 추가/삭제
      • ArrayList의 경우 원소가 중간에 추가/삭제 될 경우 해당 원소를 추가/삭제 후 그 뒤에 모든 원소들의 인덱스를 수정해주는 작업이 필요하여 비교적 속도가 느립니다.
      • LinkedList의 경우 원소가 중간에 추가/삭제 될 경우 해당 원소의 앞뒤 원소에서대한 정보만 변경해주면되기 떄문에 비교적 속도가 빠릅니다.
    • 검색
      • ArrayList의 경우 각 원소마다 인덱스 정보를 저장하고 있기 때문에 원소 검색에 비교적 속도가 빠릅니다.
      • LinkedList의 경우 각 원소마다 앞뒤 원소의 정보만 저장하고 인덱스 정보가 없기 때문에 특정 인덱스의 정보를 찾기위해서는 앞에서부터 쭉 찾아야하기 때문에 비교적 속도가 느립니다.
    반응형

    주요 메서드

    • 데이터 추가
      NO 리턴타입 메서드명 설명
      1 boolean add(E element) - 매개변수로 입력된 원소를 리스트의 마지막에 추가합니다.
      - 해당 리스트 객체를 생성할 때 제네릭 타입으로 지정한 타입만 추가할 수 있습니다.
      2 void add(int index, E element) - 매개변수로 입력된 원소를 입력한 인덱스에 추가합니다.
      - 해당 리스트 객체를 생성할 때 제네릭 타입으로 지정한 타입만 추가할 수 있습니다.
      3 boolean addAll(Collection<? extends E> c) - 매개변수로 입력된 컬렉션 전체를 리스트 마지막에 추가합니다.
      - 해당 메서드를 이용하여 해당 객체에 대하여 깊은 복사를 할 수 있습니다.
      4 boolean addAll(int index, Collection<? extends E> c) - 매개변수로 입력된 컬렉션 전체를 입력한 인덱스에 추가합니다.
      - 해당 메서드를 이용하여 해당 객체에 대하여 깊은 복사를 할 수 있습니다.
    • 데이터 변경
      NO 리턴타입 메서드명 설명
      5 E set(int index, E element) - 인덱스 위치의 원소값을 입력한 원소값으로 변경합니다.
    • 데이터 삭제
      NO 리턴타입 메서드명 설명
      6 E remove(int index) - 인덱스 위치의 원소를 삭제합니다.
      7 boolean remove(Object o) - 원소 중 매개변수 입력과 동일한 객체를 삭제합니다.
      - 매개변수 타입이 Object임으로 매개변수 입력 시 해당하는 원소의 타입과 동일한 객체로 입력해줘야합니다.
      8 void clear() - 해당 리스트의 전체 원소를 삭제합니다.
    • 데이터 정보추출
      NO 리턴타입 메서드명 설명
      9 E get(int index) - 인덱스 위치의 원소 값을 반환해줍니다.(리스트 사이즈 변동 X)
      10 int size() - 리스트 내 원소 개수를 반환해줍니다.
      11 boolean isEmpty() - 리스트 내 원소가 한개도 없으면 true, 1개 이상 있으면 false를 반환합니다.
      - empty와 null은 완전히 다른 개념으로 empty는 리스트가 비어있을 뿐 리스트는 존재한 경우 입니다.
    • 배열(Array)로 변환
      NO 리턴타입 메서드명 설명
      12 Object[] toArray() - 리스트를 Object 타입의 배열로 변환합니다.
      - Object[]이기 때문에 변환된 배열을 실제 사용시에는 해당하는 타입으로 다운캐스팅이 필요할 수 있습니다.
      13 T[] toArray(T[] t) - 리스트를 입력매개변수로 받은 타입의 배열로 변환합니다.
      - 입력매개변수의 배열 객체에서 배열의 크기를 입력해줘야합니다.(배열의 특징)
      - 리스트의 사이즈보다 작은 크기를 입력 시 자동으로 리스트 사이즈만큼으로 확장하여 배열로 변환합니다.
      - 리스트의 사이즈보다 큰 크기를 입력 시 남은 자리에 null이 들어간 배열로 변환합니다.

    💡 리스트를 배열로 변환하는건 있는데... 배열을 리스트로 변환하는건?
    toArray로 리스트를 배열로 변환하는 방법을 확인했습니다. 그러면 그 반대로 배열을 리스트로 변환하는 것도 있을까요?
    Arrays.asList()메서드를 통해 리스트로 변환할 수 있습니다.
    다만, 해당 메서드를 이용하여 만든 List의 경우 배열(Array)에 List라는 껍데기만 씌운, 래핑(wrapping)해놓은 개념으로 내부 구조는 배열과 동일합니다. 즉 사이즈를 늘리거나 줄일 수 없습니다.
    사이즈 변경이 없는 다른 List의 메서드는 모두 이용이 가능합니다.

    // 사용법
      List<제네릭 타입> 참조변수 = Arrays.asList(저장할 제네릭 타입의 데이터);
      List<제네릭 타입> 참조변수 = Arrays.asList(제네릭 타입의 배열 그자체);
      >
      // 사용예시
      List<Integer> arrToList1 = Array.asList(1, 2, 3, 4);
      String[] arr = {"가", "나", "다"};
      List<String> arrToList2 = Array.asList(arr);
      System.out.println(arrToList1);   // 출력 : [1, 2, 3, 4]
      System.out.println(arrToList2);   // 출력 : [가, 나, 다]
      arrToList1.add(5);                // 오류 발생 : UnsupportedOperationException
      arrToList2.add("라");             // 오류 발생 : UnsupportedOperationException
      arrToList1.remove(1);             // 오류 발생 : UnsupportedOperationException
      arrToList2.remove(1);             // 오류 발생 : UnsupportedOperationException
      arrToList1.clear();               // 오류 발생 : UnsupportedOperationException
      arrToList2.clear();               // 오류 발생 : UnsupportedOperationException
      arrToList1.set(0,10);             // 정상동작
      arrToList2.set(0,"화");           // 정상동작
      System.out.println(arrToList1);   // 출력 : [10, 2, 3, 4]
      System.out.println(arrToList2);   // 출력 : [화, 나, 다]
      System.out.println(arrToList1.get(2));   // 출력 : 3
      System.out.println(arrToList2.get(2));   // 출력 : 다

     

     

    • 사용 예시
      // 1. add(E element)
      List<Integer> aList = new ArrayList<Integer>();
      aList.add(1);
      aList.add(2);
      aList.add(3);
      System.out.println(aList);   // 출력 : [1, 2, 3]
      
      // 2. add(int index, E element)
      aList.add(0,10);
      aList.add(1,9);
      System.out.println(aList);   // 출력 : [10, 9, 1, 2, 3]
      
      // 3. addAll(Collection<? extends E> c)
      List<Integer> aList1 = new ArrayList<Integer>();
      List<Integer> aList2 = new ArrayList<Integer>();
      aList1.add(1);
      aList1.add(2);
      aList2.add(10);
      aList2.add(aList1);
      System.out.println(aList2);   // 출력 : [10, 1, 2]
      
      // 4. addAll(int index, Collection<? extends E> c)
      List<Integer> aList3 = new ArrayList<Integer>();
      List<Integer> aList4 = new ArrayList<Integer>();
      aList3.add(1);
      aList3.add(2);
      aList4.add(10);
      aList4.add(9);
      aList4.addAll(1, aList3);
      System.out.println(aList4);   // 출력 : [10, 1, 2, 9]
      
      // 5. set(int index, E element)
      List<Integer> aList5 = new ArrayList<Integer>();
      aList5.add(1);
      aList5.add(2);
      aList5.add(3);
      System.out.println(aList5);   // 출력 : [1, 2, 3]
      aList.set(1, 10);
      System.out.println(aList5);   // 출력 : [1, 10, 3]
      
      // 6. remove(int index)
      List<Integer> aList6 = new ArrayList<Integer>();
      aList6.add(1);
      aList6.add(2);
      aList6.add(3);
      System.out.println(aList6);   // 출력 : [1, 2, 3]
      aList6.remove(1);
      System.out.println(aList6);   // 출력 : [1, 3]
      
      // 7. remove(Object o)
      List<Integer> aList7 = new ArrayList<Integer>();
      aList7.add(1);
      aList7.add(2);
      aList7.add(3);
      System.out.println(aList7);   // 출력 : [1, 2, 3]
      aList7.remove(new Integer(1));
      // 이 때 그냥 1을 입력하면 원소 1이 아니라, 인덱스 1로 인식해버립니다.
      // 객체로 매개변수를 입력해줘야한다는 점 명심! 
      System.out.println(aList7);   // 출력 : [2, 3]
      
      //8. clear()
      List<Integer> aList8 = new ArrayList<Integer>();
      aList8.add(1);
      aList8.add(2);
      aList8.add(3);
      System.out.println(aList8);   // 출력 : [1, 2, 3]
      aList8.clear();
      System.out.println(aList8);   // 출력 : []
      
      // 9. get(int index)
      List<String> aList9 = new ArrayList<String>();
      aList9.add("가");
      aList9.add("나");
      aList9.add("다");
      System.out.println(aList9);   // 출력 : [가, 나, 다]
      System.out.println(aList9.get(0));   // 출력 : 가
      System.out.println(aList9.get(1));   // 출력 : 나
      System.out.println(aList9.get(2));   // 출력 : 다
      
      // 10. size()
      List<String> aList10 = new ArrayList<String>();
      aList10.add("가");
      aList10.add("나");
      aList10.add("다");
      System.out.println(aList10);   // 출력 : [가, 나, 다]
      System.out.println(aList10.size());   // 출력 : 3
      aList10.remove(1);
      System.out.println(aList10);   // 출력 : [가, 다]
      System.out.println(aList10.size());   // 출력 : 2
      aList10.clear();
      System.out.println(aList10);   // 출력 : []
      System.out.println(aList10.size());   // 출력 : 0
      
      // 11. isEmpty()
      List<String> aList11 = new ArrayList<String>();
      aList11.add("가");
      aList11.add("나");
      aList11.add("다");
      System.out.println(aList11);   // 출력 : [가, 나, 다]
      System.out.println(aList11.isEmpty());   // 출력 : false
      aList11.clear();
      System.out.println(aList11);   // 출력 : []
      System.out.println(aList11.isEmpty());   // 출력 : true
      
      // 12. toArray()
      List<String> aList11 = new ArrayList<String>();
      aList11.add("가");
      aList11.add("나");
      aList11.add("다");
      Object[] objArr = aList11.toArray();
      System.out.println(Arrays.toString(objArr));   // 출력 : [가, 나, 다]
      // toArray()메서드를 이용해 변환한 배열의 타입은 Object[]라는 점을 꼭 명심해야합니다.
      
      // 13. toArray(T[] t)
      List<String> aList12 = new ArrayList<String>();
      aList12.add("가");
      aList12.add("나");
      aList12.add("다");
      String[] strArr1 = aList12.toArray(new String[0]); 
      // 대상 리스트 사이즈보다 작게 입력 시 자동으로 리스트의 사이즈크기의 배열로 변환
      String[] strArr2 = aList12.toArray(new String[5]);
      // 대상 리스트 사이즈보다 크게 입력 시 남는 자리에는 null이 입력된 배열로 변환
      System.out.println(Arrays.toString(strArr1));   // 출력 : [가, 나, 다]
      System.out.println(Arrays.toString(strArr2));   // 출력 : [가, 나, 다, null, null]
    728x90

    'Study > Java' 카테고리의 다른 글

    [Java] 컬렉션 - 2) Set (HashSet, LinkedHashSet, TreeSet)  (0) 2024.09.15
    [Java] JavaBeans  (0) 2024.09.15
    [Java] 제네릭  (2) 2024.09.15
    [Java] 예외 처리  (1) 2024.09.15
    [Java] 이너 클래스  (0) 2024.09.15