컬렉션프레임웍- (2)
1.Arrays 클래스
Arrays 클래스는 배열을 다루는데 유용한 메서드를 정의하고 있다.
Arrays에 정의된 메서드들은 모두 static메서드이다.
Arrays 클래스의 정의된 메서드를 살펴 보자.
① 배열의 복사 - copyOf(), copyOfRange()
copyOf()는 배열의 전체를 복사하지만,
copyOfRange()은 배열의 일부를 복사해 새로운 배열을 만든다.
copyOfRange()에 지정된 범위의 끝은 포함되지 않는다
②배열 채우기 -fill(), setAll()
fill() - 배열의 모든 요소를 지정된 값으로 채운다
setAll() - 배열을 채우는데 사용할 함수형 인터페이스를 매개변수로 받는다.
이 메서드를 호출할 때 인터페이스를 구현한 객체를 매개변수로 지정하든가,
아니면 람다식으로 지정해야 한다.
위 문장에서, (i) -> (int) (Math.random()*5)+1) 은 람다식인데, 1~5 범위의 난수를 반환한다.
setAll() 메서드는 이 람다식이 반환하는 임의의 정수로 배열을 채운다.
③배열의 정렬과 검색 -sort(), binarySearch()
sort() - 배열을 정렬
binarySearch() - 배열에 저장된 요소를 검색
배열에서 지정된 값의 위치(index)를 찾아 반환하는데,
정렬된 상태에서만 유효값을 반환한다.
cf. 순차검색 vs 이진검색(binarySearch)
순차 검색은 첫번째 요소부터 순서대로 검색하는 반면,
이진 검색은 검색 범위를 반으로 좁혀가며 검색한다. 단, 이진검색은 배열이 정렬되어 있어야 한다.
④문자열의 비교와 출력 -equals(), toString()
일차원 배열 출력 - toString(), 다차원 배열 출력 - deepToString()
일차원 배열 비교 -equals(), 다차원 배열 비교 -deepEquals()
⑤ 배열을 List로 변환 -asList()
asList() - 배열을 List에 담아서 반환한다.
매개변수의 타입이 가변인수라서 배열 생성 없이 저장할 요소들만 나열하는 게 가능
단, asList()가 반환한 List의 크기를 변경할 수 없다.
저장된 내용을 변경할 수는 있지만, 추가/삭제는 불가능하다.
만약 크기를 변경할 수 있는 List가 필요하다면 마지막줄처럼 작성해야 한다.
String 을 char []로 변환할 때 charArray() 메서드 활용
char [] 을 String으로 변환할 때 String(char [] ) <- 생성자 활용
cf. 향상된 for문
향상된 for문은 배열 변수만 사용 가능하다.
for(변수 : 배열 변수)로 작성하면 배열의 값을 불러온다
2. Comparator 와 Comparable
Comparator 와 Comparable은 인터페이스이다.
컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다.
compare()와 compareTo()는 선언형태와 이름이 약간 다를 뿐,
두 객체를 비교하기 위한 목적으로 고안됐다.
compareTo()의 반환값은 int이지만 실제로는 비교하는 두 객체가 같으면 0,
비교하는 값보다 작으면 음수, 크면 양수를 반환한다.
Comparable - 기본 정렬기준을 구현하는데 사용
Comparator - 기본 정렬기준 외 다른 기준으로 정렬하고자 할 때 사용
예제1)
Arrays.sort()는 배열을 정렬할 때 Comparator를 지정하지 않으면
Comparable을 구현한 클래스의 객체에 구현된 내용에 따라 정렬된다.
String 의 Comparable구현은 문자열을 사전순으로 정렬하도록 작성되어 있다.
예제2)
Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있지만,
내림차순 혹은 다른 기준에 의해 정렬하고 싶을 때 Comparator를 구현해서 정렬기준을 제공할 수 있다.
Integer클래스의 compareTo()는 두 Integer객체에 저장된 값을
비교해 같으면 0, 크면 -1, 작으면 1을 반환한다.
예제3)
3. Set
Set 인터페이스 - 순서가 없고, 중복을 허용하지 않는다.
1) HashSet
HashSet은 Set인터페이스를 구현한 대표적인 컬렉션이다.
HashSet에 새로운 요소를 추가할 때 add 혹은 addAll 메서드를 사용한다.
만약 HashSet에 중복 추가를 하면 , false를 반환한다.
HashSet은 Set인터페이스의 특징대로 중복을 허용하지 않기 때문이다.
이러한 HashSet의 특징을 이용해 컬렉션 내의 중복 요소를 제거할 수 있다.
예제1)
결과에서 보여주는 것처럼, 중복된 값은 저장되지 않는다.
add메서드는 HashSet에 이미 같은 객체가 있으면 중복으로 간주하고 저장하지 않는다.
그리고 작업이 실패했다는 의미로 false를 반환한다.
Set을 구현한 컬렉션 클래스 HashSet은 순서를 유지하지 않기 때문에
저장한 순서와 다를 수 있다.
만약 중복 제거 + 순서 유지를 원한다면 LinkedHashSet을 사용해야 한다.
예제2)
예제3)
Ex11_11에서 실행결과, 두 인스턴스 name, age의 값이 같음에도 불구하고
서로 다른 것으로 인식하여 ‘David:10’이 두번 출력되었다.
HashSet 은 중복을 허용하지 않는데 왜 그런 걸까?
HashSet의 add메서드는 새로운 요소를 추가하기 전에
기존에 저장된 요소와같은 것인지 판별하기 위해 equals()와 hashcode()를 호출하기 때문에
equals()와 hashcode() 모두 목적에 맞게 오버라이딩 해야 한다.
예제4)
2) TreeSet
TreeSet은 이진 탐색 트리라는 자료구조 형태로 데이터를 저장하는 컬렉션 클래스다.
TreeSet은 이진 탐색 트리의 성능을 향상시킨 ‘레드-블랙 트리’로 구현되어 있다.
TreeSet은 인터페이스Set을 구현했으므로
중복된 데이터의 저장을 허용하지 않으며, 저장순서를 유지하지도 않는다.
이진트리는 링크드리스트처럼 여러 개의 노도로 서로 연결된 구조로,
각 노드에 최대 2개의 노드를 연결할 수 있으며
‘루트’라고 불리는 하나의 노드로부터 시작해서 계속 확장해나갈 수 있다.
위-아래 연결된 두 노드를 부모-자식에 있다하며
위의 노드를 부모 , 아래 노드를 자식 노드라고 한다.
하나의 부모는 최대 두개의 자식 노드와 연결될 수 있다.
이진 트리의 노드를 코드로 표현하면 다음과 같다.
Class TreeNode {
TreeNod left; //왼쪽 자식노드
Object element; //객체를 저장하기 위한 참조 변수
TreeNode right; //오른쪽 자식 노드
}
데이터를 저장하기 위한 Object 타입의 참조변수 하나와
두개의 노드를 참조하기 위한 두개의 참조변수를 선언했다.
이진탐색 트리는 부모노드의 왼쪽에는 부모노드의 값보다 작은 값의 자식노드를,
오른쪽에는 부모노드의 값보다 큰 자식 노드를 저장하는 이진트리이다.
왼쪽 마지막 값부터 오른쪽 값까지 읽으면 왼쪽 노드->부모노드->오른쪽노드 순으로
오름차순으로 정렬된 순서를 얻어올 수 있다.
TreeSet은 이처럼 정렬된 상태를 유지하기 때문에 단일 값 검색과 범위 검색이 매우 빠르다.
트리는 순차적으로 저장하는 게 아니라, 저장 위치를 찾아 저장해야 하고,
삭제하는 경우 트리의 일부를 재구성해야 하므로 링크드 리스트보다 데이터 추가,삭제 시간은 더 소요된다.
대신 배열, 링크드 리스트에 비해 검색과 정렬 기능이 더 뛰어나다.
예제1)
예제2)
예제3)
5. Map
Map 인터페이스는 순서가 없다.
key는 중복을 허용하지 않지만, value는 중복을 허용한다. 키와 값을 entry라고 한다.
cf. HashMap, TreeMap. LinkedHashMap 은 순서가 있음
1) HashMap
Hashtable과 HashMap의 관계는 Vector와 ArrayList의 관계와 같다.
Hashtable보다는 새로운 버전인 HashMap 사용을 권장한다.
HashMap은 인터페이스 Map을 구현했으므로 Map의 특징을 갖는다.
키와 값을 묶어서 하나의 데이터(entry)로 저장한다는 특징이 있다.
또한, 해싱(hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 뛰어나다.
HashMap은 키와 값을 각각 Object타입으로 저장한다.
즉 (Object, Object)의 형태로 저장하기 때문에 어떠한 객체도 저장할 수 있지만
키는 주로 String을 대문자 또는 소문자로 통일해서 사용하곤 한다.
키(Key) 컬렉션 내의 키(key) 중에서 유일해야 한다.
값(Value) 키(Key)와 달리 데이터의 중복을 허용한다.
키는 저장된 값을 찾는데 사용되므로 컬렉션 내에서 유일해야만 한다.
즉, HashMap에 저장된 데이터를 하나의 키로 검색했을 때 결과가 단 하나여야만 한다.
예제1)
예제2)
예제3)
6. Collections 클래스
Collections 클래스는 컬렉션과 관련된 메서드(static)을 제공한다.
1) 컬렉션 채우기, 복사, 정렬, 검색 - fill(), copy(), sort(), binarySearch() 등
2) 컬렉션 동기화 - SynchronizedXXX()
구번전인 Vector와 Hashtable와 달리,
ArrayList와 HashMap과 같은 컬렉션은 동기화되어 있지 않다.
필요한 경우에만 동기화를 한다.
동기화를 사용하는 방법
List syncList = Collections.synchronizedList(new ArrayList(...));
3) 컬렉션 변경불가
컬렉션에 저장된 데이터를 보호하기 위해, 즉 읽기전용으로 만들어야 하는 때가 있다.
이때 unmodifiable이 붙은 메서드를 사용하면 된다.
4) 싱글톤 컬렉션 만들기 -singletonXXX()
싱글톤 컬렉션은 객체 1개만 저장하는 컬렉션이다.
static List singletoneList(Object o)
static Set singleton(Object o) //singletonSet이 아님 주의
static Map singletonMap(Object key, Object value)
5) 한 종류의 객체만 저장하는 컬렉션 만들기 - checkedXXX()
컬렉션에는 여러개의 객체를 저장할 수 있는데 checked를 쓰면 한 종류의 객체만 저장할 수 있다.
사용 방법
List list = new ArrayList();
List checkedList = checkedList(list, String.class); //String만 저장 가능
checkedList.add(“abc”); //ok
checkedList.add(new Integer(3)); //에러 발생.
'Java' 카테고리의 다른 글
Java 쓰레드 (0) | 2022.04.29 |
---|---|
Java 지네릭스, 열거형, 애너테이션 (0) | 2022.04.28 |
Java 컬렉션 프레임웍 - (1) (0) | 2022.04.26 |
Java 날짜와 시간 & 형식화 (0) | 2022.04.18 |
java.lang패키지와 유용한 클래스-(1) (0) | 2022.04.15 |