List<E> 컬렉션 인터페이스

jaegeunsong97·2023년 1월 20일
0
post-thumbnail

2023_1_20_TIL

배열과 리스트의 차이점

  • 차이점 -> 저장 공간의 크기가 고정(배열)? 동적(리스트)?
public class ArrayVsList {
    public static void main(String[] args) {
        String[] array = new String[] {"가","나","다","라","마","바","사"} ;
        System.out.println(array.length);
        array[2] = null;
        array[3] = null;
        System.out.println(array.length);
        System.out.println(Arrays.toString(array));
        System.out.println();

        List<String> aList = new ArrayList<>();
        System.out.println(aList.size());
        aList.add("가");aList.add("나");aList.add("다");aList.add("라");
        aList.add("마");aList.add("바");aList.add("사");
        System.out.println(aList.size());
        aList.remove("다");
        aList.remove("바");
        System.out.println(aList.size());
        System.out.println(aList);
    }
}

List< E > 객체 생성하기

  • List< E >는 인터페이스이기 때문에 객체 생성 불가

    • 따라서, 상속받아 자식 클래스를 생성 후, 자식 클래스를 이용해 객체를 생성
    • ArrayList, LinkedList, Vector 클래스들이 존재
  • List< E > 인터페이스 구현 클래스 생성자로 동적 컬렉션 객체 생성

    • List가 Generic 형태 -> 상속되는 자식클래스들도 Generic
    • 객체 생성시, 일반적으로 기본 생성자 사용, 하지만 capacity를 매개변수로 포함하고 있는 생성자를 사용할 수 있음
    • capacity는 실제 데이터의 개수를 나타내는 저장공간(size)와는 다른 개념, 데이터를 저장하기 위해 미리 할당해 놓은 메모리의 크기라고 생각
  • Arrays.asList() 메소드를 이용해 정적 컬렉션 객체 생성

    • 내부적으로 배열을 먼저 선언 -> List< E >로 Wrapping하는 것
    • 내부구조는 배열과 동일 -> 컬렉션 객체이지만 '저장공간의 크기 변경 불가능'
      • 구현 클래스로 객체 생성 후, add() remove() 불가능, set() 가능 -> 고정된 데이터를 활용할 때 많이 사용
public class CreateListObject {
    public static void main(String[] args) {
        List<Integer> aList1 = new ArrayList<>();
        List<Integer> aList2 = new ArrayList<>(30);
        List<Integer> aList3 = new Vector<>();
        List<Integer> aList4 = new Vector<>(30);
        List<Integer> aList5 = new LinkedList<>();

        List<Integer> aList7 = Arrays.asList(1,2,3,4);
        List<String> aList8 = Arrays.asList("안녕", "방가");
        aList7.set(1, 7);
        aList8.set(0, "감사");

        System.out.println(aList7);
        System.out.println(aList8.toString());// toString() 생략가능 -> List 오버라이딩
    }
}

List< E >의 주요 메소드 중 toArray()

  • Object[ ] 반환 형태 -> 특정 타입으로 다운 캐스팅 필요
  • 특정 타입의 배열로 리턴 형태 -> toArray(T[ ] t)
    • 리스트의 데이터 개수 < 배열의 객체 크기
      • 입력된 배열 크기가 확장되어서 리턴
    • 리스트의 데이터 개수 > 배열의 객체 크기
      • 입력된 배열 크기가 그대로 리턴

ArrayList< E > 구현 클래스

  • 특징
    • 데이터를 인덱스로 관리
    • 저장공간 동적으로 관리
    • 동기화(synchrosized X, Single Thread)
  • 데이터 추가하기 - add()
    • addAll()
  • 데이터 변경하기 - set()
  • 데이터 삭제하기 - remove(), clear()
  • 데이터 정보 추출하기 - isEmpty(), size(), get(int index)
  • 배열로 변환하기 - toArray(), toArray(T[ ] t)
public class ArrayListMethod {
    public static void main(String[] args) {
        List<Integer> aList1 = new ArrayList<>();

        aList1.add(3);
        aList1.add(4);
        aList1.add(5);
        System.out.println(aList1.toString());

        aList1.add(1, 6);
        System.out.println(aList1.toString());

        List<Integer> aList2 = new ArrayList<>();
        aList2.add(1);
        aList2.add(2);
        aList2.addAll(aList1);
        System.out.println(aList2.toString());

        List<Integer> aList3 = new ArrayList<>();
        aList3.add(1);
        aList3.add(2);
        aList3.addAll(1, aList3);
        System.out.println(aList3);

        aList3.set(1, 5);
        aList3.set(3, 6);
        System.out.println(aList3);

        aList3.remove(1);
        System.out.println(aList3);

        aList3.remove(new Integer(2));// 컬렉션의 원소에는 객체만 올 수 있음
        System.out.println(aList3);

        aList3.clear();
        System.out.println(aList3);

        System.out.println(aList3.isEmpty());

        System.out.println(aList3.size());
        aList3.add(1);
        aList3.add(2);
        aList3.add(3);
        System.out.println(aList3);
        System.out.println(aList3.size());

        for (int i = 0; i < aList3.size(); i++) {
            System.out.println(i + "번째: " + aList3.get(i));
        }
        Object[] objects = aList3.toArray();
        System.out.println(Arrays.toString(objects));

        Integer[] integers1 = aList3.toArray(new Integer[4]);// null 1개추가
        System.out.println(Arrays.toString(integers1));

        Integer[] integers2 = aList3.toArray(new Integer[5]);// null 2개 추가
        System.out.println(Arrays.toString(integers2));
    }
}

Vector< E > 구현 클래스

  • List< E >상속함 -> 메모리 동적 할당 가능 -> List< E > 공통적인 특성 모두 가짐
  • (동기화) Synchronized O -> Multi Thread 완벽
    • 하나의 스레드인 경우에는 ArrayList 사용(효울적)
  • Vector 메소드는 위의 ArrayList와 동일한 메소드를 가진다
    • 생략

LinkedList< E > 구현 클래스

  • 동기화(Synchronized X, Single Thread)
  • capacity를 매개변수로 받는 생성자 없음(Vector, ArrayList 다 있음)
    • 객체를 지정할 때 capacity 지정 불가능
  • 내부 저장방식의 차이점
    • ArrayList
      • 데이터를 위치 정보(index) 값으로 저장
    • LinkedList
      • 앞뒤 객체의 정보 저장 -> 모든 데이터 연결
  • LinkedList 메소드는 위의 ArrayList와 동일한 메소드를 가진다
    • 생략

ArrayList< E >와 LinkedList< E >의 성능 비교

  • ArrayList
    • 장점 -> 데이터 인덱스로 접근(탐색 매우 빠름, get())
    • 단점 -> add(), remove() 매우 느림 -> 변경시, 모든 데이터들 이동 필요
  • LinkedList
    • 장점 -> add(), remove() 매우 빠름 -> 앞뒤 노드의 연결만 신경 쓰면 되어서
    • 단점 -> 데이터 무조건 앞에서 부터 (탐색 매우 느림, get())
  • currentTimeMillis() and nanoTime()
    • 모두 System 클래스 정적 매소드
    • currentTimeMillis()
      • 1970년 1월 1일 기준으로 현재 시간과의 차이를 long형으로 리턴
    • nanoTime()
      • 현재의 시간 정보와는 관계 없으며, 상대적인 시간 차이를 나노초 단위로 구분
long startTime = System.nanoTime();
long endTime = System.nanoTime();
// 측정 시간 = startTime() - endTime();
public class ArrayListVsLinkedList {
    public static void main(String[] args) {
        List<Integer> aList = new ArrayList<>();
        List<Integer> linkedList = new LinkedList<>();
        long startTime = 0, endTime = 0;

        //
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            aList.add(0, i);
        }
        endTime = System.nanoTime();
        System.out.println("ArrayList 데이터 추가 시간 = " + (endTime - startTime) + " ns");

        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            linkedList.add(0, i);
        }
        endTime = System.nanoTime();
        System.out.println("LinkedList 데이터 추가 시간 = " + (endTime - startTime) + " ns");

        //
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            aList.get(i);
        }
        endTime = System.nanoTime();
        System.out.println("ArrayList 데이터 검색 시간 = " + (endTime - startTime) + " ns");

        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            linkedList.get(i);
        }
        endTime = System.nanoTime();
        System.out.println("LinkedList 데이터 검색 시간 = " + (endTime - startTime) + " ns");

        //
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            aList.remove(0);
        }
        endTime = System.nanoTime();
        System.out.println("ArrayList 데이터 삭제 시간 = " + (endTime - startTime) + " ns");

        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            linkedList.remove(0);
        }
        endTime = System.nanoTime();
        System.out.println("LinkedList 데이터 삭제 시간 = " + (endTime - startTime) + " ns");
    }
}

참조

https://incheol-jung.gitbook.io/docs/q-and-a/java/collection

profile
현재 블로그 : https://jasonsong97.tistory.com/

0개의 댓글