velog에서 이전한 글 입니다.

List

ArrayList(Vector)

  • 요소를 삭제할 경우 삭제할 객체의 바로 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 객체를 덮어씐다. 마지막 데이터는 null로 변경한다. 그래서 맨 위의 데이터를 수정/삭제하는데 느리다.
  • 추가도 이후 요소들을 모두 한칸 씩 이동시킨다.
  • 크기를 변경할 수 없다. 내부적으로 새로운 배열을 생성해서 데이터를 복사한다.

LinkedList

  • 배열은 모든 데이터가 연속적으로 존재하지만 링크드 리스트는 불연속적으로 존재하는 데이터를 서로 연결한 형태이다.

  • 요소를 삭제할 경우 삭제하고자하는 요소의 이전요소가 삭제하고자 하는 요소의 다음 요소를 참조하도록 변경하기만 하면 된다.
  • 추가도 참조만 변경해주면 된다.
  • 읽기가 느리다. n번째 값을 얻기 위해 n번째 데이터까지 차례대로 따라가야 한다.

결론 : 데이터 개수가 변하지 않는 경우라면 ArrayList, 데이터 개수 변경이 잦다면 LinkedList를 사용하자.
변경이 잦아도 순차적(뒤부터 추가/삭제 한다면)이라면 ArrayList도 고려할 수 있다.

Stack/Queue

일반적으로 순차적으로 데이터를 추가 삭제하는 Stack은 ArrayList가 더 적합하고
첫 번째 저장된 데이터를 삭제하는 Queue는 LinkedList가 더 적합하다.

public class Main {
    public static void main(String[] args) {
        Stack st = new Stack();
        Queue q = new LinkedList();
    }
}

java에서 Stack은 구현된 클래스를 제공하고 Queue는 인터페이스만 정의해 놓았다.
LinkedList는 Queue인터페이스를 구현한 클래스이기도 하다.

Arrays

public class Main {
    public static void main(String[] args) {
        int[] test = new int[10];
        int count = 0;

        Arrays.fill(test, 5);
        System.out.println(Arrays.toString(test));

        Arrays.setAll(test, (v) -> {
            //count++; 
            // Variable used in lambda expression should be final or effectively final
            return (int) (Math.random() * 5);
        });
        System.out.println(Arrays.toString(test));
    }
}

결과
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
[0, 4, 2, 3, 1, 4, 0, 1, 2, 0]

setAll()은 배열을 채우는데 사용할 함수형 인터페이스를 매개변수로 받는다.
람다식에서 사용하는 변수는 final이여야 한다.

public class Main {
    public static void main(String[] args) {
        int[] t1 = new int[10];
        int[] t2 = new int[10];
        int[][] test = new int[10][10];
        int[][] test2 = new int[10][10];
        int[][][] test3 = new int[10][10][10];
        int[][][] test4 = new int[10][10][10];

        System.out.println(t1.equals(t2));
        System.out.println(Arrays.equals(test, test2));
        System.out.println(Arrays.deepEquals(test, test2));
        System.out.println(Arrays.deepEquals(test3, test4));
    }
}

결과
false
false
true
true

Array instance.equals() : 비교연산자(==)랑 동일
Arrays.equals() : 값 비교
Arrays.deepEquals() : 다차원 값 비교

Comparator/Comparable

public class Main {
    public static void main(String[] args) {
        Character[] t = {'a','b','c','d','e'};
        Arrays.sort(t);
        System.out.println(Arrays.toString(t));

        Arrays.sort(t, new Descending());
        System.out.println(Arrays.toString(t));
    }
}

class Descending implements Comparator{
    public int compare(Object o1, Object o2){
        if( o1 instanceof Comparable && o2 instanceof Comparable){
            Comparable c1 = (Comparable) o1;
            Comparable c2 = (Comparable) o2;
            return c1.compareTo(c2) * -1;
        }
        return -1;
    }
}

결과
[a, b, c, d, e]
[e, d, c, b, a]

Comparable : 기본 정렬기준을 구현하는데 사용
Comparator : 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용

Comparable 소스
public interface Comparable<T> {
    public int compareTo(T o);
}

Arrays.sort(arr)로 동작하는 것은 arr type(ex_ Integer)의 compareTo로 정렬한다.

Iterator

Iterator, ListIterator, Enumeration은 모두 컬렉션 요소 접근에 사용되는 인터페이스이다.
Collection interface는 iterator()를 정의하고 있다.

public class Main {
    public static void main(String[] args) {
        List<Integer> t = Arrays.asList(new Integer[2]);
        Iterator it = t.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("===========");
        for(int i=0; i<t.size(); i++){
            Integer val = t.get(i);
            System.out.println(val);
        }
    }
}
결과
null
null
===========
null
null

위와 같이 사용한다.

Map m = new HashMap();
Set t = m.entrySet();
Iterator it = t.iterator();

map의 경우 entrySet(), keySet()을 이용