🏃♂️ 들어가기 앞서..
본 게시물은 스터디 활동 중에 작성한 게시물로 자바의 정석-기초편 교재를 학습하여 정리하는 글입니다.
※ 스터디 Page : 〔투 비 마스터 : 자바〕
*해당 교재의 목차 순서와 구성을 참고하여 작성하며
각 내용마다 부족할 수 있는 내용이나 개인적으로 궁금한 점은
추가적인 검색을 통해 채워나갈 예정입니다.
Arrays
클래스배열을 다루는데 있어 유용한 메서드들이 정의되어 있는 클래스
같은 기능의 메서드가 배열 타입에 따라 " 오버로딩(Overloading) " 되어있음.
( 정의된 메서드 모두 static 메서드 )
copyOf()
/ copyOfRange()
copyof()
: " 배열 전체 "를 복사해서 새로운 배열 생성 & 반환
(인수로 "끝 범위" 지정 가능 : 지정된 범위의 '끝' 은 포함 X )
copyOfRange()
: " 배열의 일부 "를 복사해서 새로운 배열 생성 & 반환
( 인수로 "시작 범위" & "끝 범위" 지정 가능 : 지정된 범위의 '끝' 은 포함 X )
int[] arr = {0, 1, 2, 3, 4, 5 } ;
int[] arr2 = Arrays.copyOf( arr, arr.length ) ; // [0, 1, 2, 3, 4, 5]
int[] arr3 = Arrays.copyOf( arr, 3 ) ; // [0, 1, 2]
int[] arr4 = Arrays.copyOf( arr, 7 ) ; // OutOfRange 값은 '0'으로 채움 _ [0, 1, 2, 3, 4, 5, 0]
int[] arr5 = Arrays.copyOfRange( arr, 2, 4 ) ; // [2, 3] _ 끝 포함 X
int[] arr6 = Arrays.copyOfRange( arr, 0, 7 ) ; // [0, 1, 2, 3, 4, 5, 0]
fill()
배열의 모든 요소를 " 지정된 값 "으로 채움
int[] arr = new int[5] ;
Arrays.fill( arr, 9 ) ; // arr = [9, 9, 9, 9, 9]
setAll()
배열을 모두 채우는데 채울 값을 도출하는 " 함수형 인터페이스 "를 매개변수로 받음
→ 함수에 따라 값이 생성되어 채워짐
( " 함수형 인터페이스를 구현한 객체 " or " 람다식 " )
int[] arr = new int[5] ;
Arrays.setAll( arr, (i) -> (int)(Math.random()*5) + 1 ) ; // arr = [2, 1, 3, 3, 5]
sort()
int[] arr = { 3, 1, 4, 0, 2 } ;
Arrays.sort(arr) ; // Integer에 정의된 기준에 의해 정렬 -> 오름차순 정렬
System.out.println(Arrays.toString(arr)) ; // [0, 1, 2, 3, 4]
binarySearch()
_ 이진 검색배열에서 " 지정된 값이 저장된 위치 (index) "를 반환
★ 배열이 반드시 정렬된 상태이어야 올바른 결과
( 검색 값이 여러개 존재하면 무작위 )
int[] arr = { 3, 1, 4, 0, 2 } ;
/* 정렬 X */
int idx = Arrays.binarysearch(arr, 2); // 값 2의 index
// idx = -5 _ 정렬이 안되어 있기 때문에 잘못된 값 추출
Arrays.sort(arr) ; // [0, 1, 2, 3, 4]
int idx = Arrays.binarysearch(arr, 2); // 정렬된 배열에서 값 2의 index
// idx = 2
이전에 TreeSet을 배웠을 때 알 수 있듯
첫 번째 요소부터 순서대로 하나씩 비교 검색하는 " 순차 검색( linear search ) "과는 달리
이 " 이진 검색( binary search ) "은
검색 속도가 굉장히 빠르다.
toString()
- 일차원 배열 출력 :
toString()
- 다차원 배열 출력 :
deepToString()
int[] arr = {0,1,2,3,4} ;
int[][] arr2D = {{11,12},{21,22}} ;
System.out.println(Arrays.toString(arr)) ; // [0, 1, 2, 3, 4]
System.out.println(Arrays.deepToString(arr2D)) ; // [[11, 12], [21, 22]]
equals()
- 일차원 배열 비교 :
equals()
- 다차원 배열 비교 :
deepEquals()
* 같으면 true / 다르면 false
" 다차원 배열 "에 equals()
를 사용하게 되면
저장된 내용이 같더라도
" 배열에 저장된 배열의 주소 "를 비교하게 되기 때문에
false가 나오게 된다.
String[][] str2D = new String[][]{{"aaa", "bbb"},{"aaa", "bbb"}} ;
String[][] str2D2 = new String[][]{{"aaa", "bbb"},{"aaa", "bbb"}} ;
System.out.println(Arrays.equals(str2D, str2D2)) ; // false _ 각 '배열'이 저장된 메모리 주소는 다르기 때문에
System.out.println(Arrays.deepEquals(str2D, str2D2)) ; // true
asList()
매개변수 타입이 " 가변인수 "이기 때문에
배열 입력이 아닌 저장할 요소들 나열하는 것도 가능하다.
asList( Object... a )
메서드는
배열을 List에 담아 반환하는데
위와 같이 매개변수의 타입이 가변인수( ...
)인 것을 알 수 있다.
즉,
배열 생성을 안하고
저장할 요소들만 나열해도 동일하게
해당 요소들로 구성된 List로 반환한다.
단 asList()
를 통해 반환된 List는
"내용 변경"은 가능하나
크기 변경( 추가/삭제 )이 불가능하다.
( 읽기 전용 )
그렇기 때문에 크기 변경이 가능한 List로 사용하기 위해서는
새로운 ArrayList
타입 객체로 생성해야 한다.
List list1 = Arrays.asList(new Integer[]{1,2,3,4,5}) ; // list1 = [1, 2, 3, 4, 5]
List list2 = Arrays.asList(1,2,3,4,5) ; // list2 = [1, 2, 3, 4, 5]
/* 하지만 크기변경 _ 추가삭제가 불가능하다 */
list.add(6) ; // UnsupportedOperationException 예외 발생
/*
추가/삭제 작업이 가능한 리스트로 만들기 위해선
ArrayList타입 인스턴스로 생성해야 함.
*/
List list3 = new ArrayList(Arrays.asList(1,2,3,4,5)) ;// list3 = [1, 2, 3, 4, 5]
list.add(6) ; // list3 = [1, 2, 3, 4, 5, 6]
Collections
클래스
fill()
나copy()
,sort()
,binarySearch()
등 등의 메서드들은
앞서 알아봤던 Arrays와 함께 모두 포함되어 있고 같은 기능을 하기때문에 생략
synchronized~ ()
< 멀티 쓰레드 (multi - thread) 프로그래밍 >
▶ 하나의 객체를 여러 쓰레드가 동시에 접근할 수 있는 환경
▶ " 데이터 무결성 유지 "를 위해 공유되는 객체에 동기화
* 동기화 = synchronization
Vector
와 Hashtable
과 같은 구버전 클래스들에는
자체적으로 동기화 처리가 되어 있는데
이는 싱글 쓰레드 프로그래밍의 경우에는 낭비가 발생한다.
위와 같은 낭비를 방지하고 개선한 것이
새로 추가된 ArrayList
와 HashMap
과 같은 클래스들이다.
처음부터 동기화를 자체적으로 처리하는 것이 아닌
" 필요할 때 java.util.Collections
클래스의 동기화 메서드를 이용해서 동기화 처리 "하는 방식이다.
그 Collections 클래스의 동기화 메서드가
synchronized~ ()
메서드이다.
static Collection synchronizedCollection( Collection c )
static List synchronizedList( List list )
static Set synchronizedSet( Set s )
static Map synchronizedMap( Map m )
static SortedSet synchronizedSortedSet( SortedSet s )
static SortedMap synchronizedSortedMap( SortedMap m )
/* 사용 방법 */
List synchroList = Collections.synchronizedList( new ArrayList(...) ) ; // ArrayList는 동기화 되지 않은 List
unmodifiable~ ()
컬렉션에 저장된 데이터를 보호하기 위해서 변경할 수 없게끔
" 읽기 전용 " 컬렉션 생성* 멀티쓰레드 프로그래밍에서 여러 쓰레드가 하나의 컬렉션을 공유할 경우, " 손상 가능성 "이 있을 때, 사용
static Collection unmodifiableCollection( Collection c )
static List unmodifiableList( List list )
static Set unmodifiableSet( Set s )
static Map unmodifiableMap( Map m )
static SortedSet unmodifiableSortedSet( SortedSet s )
static NavigableSet unmodifiableNavigableSet( NavigableSet s )
static SortedMap unmodifiableSortedMap( SortedMap m )
static NavigableMap unmodifiableNavigableMap( NavigableMap m )
singleton~ ()
단 한 개의 객체만 저장하는 컬렉션으로 " 한개의 요소 "로 이루어져 있다.
이 또한 반환된 컬렉션은 변경할 수 없다.
static List singletonList( Object o )
static Set singleton( Object o ) // Set는 그냥 singleton
static Map singletonMap( Object key, Object value )
checked~ ()
" 컬렉션에 모든 종류의 객체를 저장할 수 있다. "라는 특징이
장점이긴 하나
어찌보면
이전에 알아봤던 Iterator로 표준화된 코드 등과 같이 신경써서 프로그래밍해야 한다는 불편함이 있다.
하나의 통일된 타입으로 객체들을 저장하면
해당 Collection의 각 객체에 대한 독립적인 관리와 처리가 용이해지기에
필요한 경우가 있다.
static Collection checkedCollection( Collection c, Class type )
static List checkedList( List list, Class type )
static Set checkedSet( Set s, Class type )
static Map checkedMap( Map m, Class keyType, Class valueType ) // 각 각 Type 지정
static Queue checkedQueue( Queue queue, Class type )
static SortedSet checkedSortedSet( SortedSet s, Class type )
static NavigableSet checkedNavigableSet( NavigableSet s, Class type )
static SortedMap checkedSortedMap( SortedMap m, Class keyType, Class valueType )
static NavigableMap checkedNavigableMap( NavigableMap m, Class keyType, Class valueType )
/* 사용 방법 */
List list = new ArrayList() ;
List checkedList = checkedList( list, String.class ) ; //String만 저장 가능하도록
checkedList.add("abc") ; // 가능
checkedList.add(new Integer(123)) ; // 불가능(에러) : ClassCastException 발생
※ 유용한 Collections 메서드
addAll( [배열] , ... )
: 지정 Collection 에 '입력된 값들( 가변인자 )'을 추가rotate( [배열] , int move )
: 오른쪽으로 move 칸씩 이동swap( [배열], int idx1, int idx2)
: "idx1 위치의 값"과 "idx2 위치의 값"과 교환shuffle( [배열] )
: 무작위 섞기sort( [배열], reverseOrder())
: 역순 정렬 == "reverse( [배열] )
"
disjoint( [배열 1], [배열 2] )
: 두 배열에 " 공통요소가 있으면 " truenCopies( [배열].size(), Object value )
: 지정 배열과 같은 크기의 새로운 리스트 생성 & value로 해당 리스트 채움 ( 자동 fill _ copy & fill )
" 지네릭스(Generics) "로 컬렉션에 저장할 요소 타입을 제한할 수 있지만
이 방법은 JDK1.5부터 가능한 방법이기 때문에
이전 버젼과의 호환이 되지 않는다.
(그렇기 때문에 위와 같은 checked 를 통한 타입 제한 방법을 알아두고 사용하는 것이 좋다.)