// Collection의 stream 메서드를 이용하여 Stream 얻기
List<String> list = Arrays.asList("HAN", "HAN", "KANG", "KIM", "PARK", "HWANG");
// sorted() 메서드
// 오름차순
list.stream().sorted().forEach(s -> System.out.println("sorted : " + s));
/*
※ 정렬 전
forEach : HAN
forEach : HAN
forEach : KANG
forEach : KIM
forEach : PARK
forEach : HWANG
※ 정렬 후
sorted : HAN
sorted : HAN
sorted : HWANG
sorted : KANG
sorted : KIM
sorted : PARK
*/
Arrays 클래스에는 배열을 다루기 위한 다양한 메소드가 포함되어 있다. Arrays 클래스의 모든 메소드는 클래스 메소드(static method)이므로, 객체를 생성하지 않고도 바로 사용할 수 있다.
■ Arrays 대표적인 메서드 정리
메서드
설명
static Object[] copyOf(Object[] original, int newLength)
배열을 원하는 길이만큼 복사한 배열을 반환한다.
static Object[] copyOfRange(Object[] original, int from, int to)
배열의 복사를 지정한 부분(시작 인덱스부터 끝 인덱스까지)을 복사한 배열을 반환한다.
static void fill(Object[] a, int fromIndex, int toIndex, Object val)
배열의 지정한 부분(시작 인덱스부터 끝 인덱스까지)을 원하는 값으로 변환하고, fromIndex, toIndex 매게변수가 없을경우 배열전체값을 변환
static void sort(Object[] a, int fromIndex, int toIndex)
배열의 지정한 부분(시작 인덱스부터 끝 인덱스 -1 까지)만을 오름차순 정렬하고, fromIndex, toIndex 매게변수가 없을경우 배열전체를 정렬
static int binarySearch(Object[] a, int fromIndex, int toIndex, Object key)
sort()정렬이 선행되어야 정확한 위치를 반환한다. 배열의 지정한 부분(시작 인덱스부터 끝 인덱스까지)에 해당하는 값들 중 찾고자하는 key값에 index를 반환하고, int fromIndex, int toIndex 매게변수가 없을경우 배열전체 중 찾고자하는 key값에 index를 반환
■ copyOf 메서드 활용
int[] nums = {1,2,3,4,5};
// 배열 복사 : 첫번째 인덱스부터 두번째 인자값에 지정한 갯수만큼 복사
int[] copyOfArr = Arrays.copyOf(nums, 3);
System.out.println("copyOf : " + Arrays.toString(copyOfArr));
/*
※ 출력 결과
copyOf : [1, 2, 3]
*/
■ copyOfRange 메서드 활용
int[] nums = {1,2,3,4,5};
// 배열 원하는 위치 복사 : 두번째 인자 위치부터 세번째 인자 위치-1 까지의 배열 복사
int[] copyOfRangeArr = Arrays.copyOfRange(nums, 1, 4);
System.out.println("copyOfRange : " + Arrays.toString(copyOfRangeArr));
/*
※ 출력 결과
copyOfRange : [2, 3, 4]
*/
■sort 메서드 활용
// 배열의 정렬 : 두번째 인자 위치부터 세번째 인자 위치-1 까지의 배열을 오름차순 정렬
int[] sortNums = {5,4,3,2,1};
Arrays.sort(sortNums, 1, 4);
// 배열의 전체 원소를 오른차순 정렬
// Arrays.sort(sortNums);
// 결과 : [1,2,3,4,5]
System.out.println("sort : " + Arrays.toString(sortNums));
/*
※ 출력 결과
sort : [5, 2, 3, 4, 1]
*/
■binarySearch 메서드 활용
int[] nums = {1,2,3,4,5};
// 원하는 원소의 인덱스 찾기
System.out.println("binarySearch : " + Arrays.binarySearch(nums, 4));
// 오름차순 정렬이 되어있지 않은 배열의 원소 인덱스를 제대로 찾아오지 못한다.
System.out.println("binarySearchErr : " + Arrays.binarySearch(new int[] {5,4,3,2,1}, 4));
/*
※ 출력 결과
binarySearch : 3
binarySearchErr : -6
*/
■fill 메서드 활용
int[] nums = {1,2,3,4,5};
// 배열의 원소값 변환 : 두번째 인자 위치부터 세번째 인자 위치-1 까지의 배열을 원소값 수정
Arrays.fill(nums, 1, 4, 6);
// 배열의 전체 원소를 수정
// Arrays.fill(nums, 6);
// 결과 : [6,6,6,6,6]
System.out.println("fill : " + Arrays.toString(nums));
/*
※ 출력 결과
fill : [1, 6, 6, 6, 5]
*/
문자열 str를 특정 구분자(delim)로 분리 returnDelims 가 true : 구분자 포함 returnDelims 가 false : 구분자 불포함
■ StringTokenizer 메서드 정리
메서드
설명
boolean hasMoreTokens() boolean hasMoreElements()
토큰이 존재하면 true, 토큰이 존재하지 않으면 false 반환
Object nextElement()
다음 토큰을 Object형으로 반환
String nextToken()
다음 토큰을 String형으로 반환
int countTokens()
토큰의 갯수를 int형으로 반환
■ 기본 구분자 (delim : \t, \n, \r)
// 기본 구분자 : \t\n\r
StringTokenizer defaultTokens = new StringTokenizer("write once \t run \r anywhere");
while (defaultTokens.hasMoreTokens()) {
System.out.println(defaultTokens.nextToken());
}
/*
※ 출력 결과
write
once
run
anywhere
*/
■특정 구분자
// 구분자 : #/-
StringTokenizer delimTokens = new StringTokenizer("write#once/run-anywhere", "#/-");
while (delimTokens.hasMoreElements()) {
System.out.println(delimTokens.nextElement());
}
/*
※ 출력 결과
write
once
run
anywhere
*/
■구분자 포함/불포함 분리
true : 구분자 포함
// 구분자를 포함한 토큰 추출 : #/-
StringTokenizer returnDelimsTokens = new StringTokenizer("write#once/run-anywhere", "#/-", true);
// 토큰의 갯수 반환
System.out.println(returnDelimsTokens.countTokens());
while (returnDelimsTokens.hasMoreTokens()) {
System.out.println(returnDelimsTokens.nextToken());
}
/*
※ 출력 결과
7
write
#
once
/
run
-
anywhere
*/
false : 구분자 불포함
// 구분자를 포함한 토큰 추출 : #/-
StringTokenizer returnDelimsTokens = new StringTokenizer("write#once/run-anywhere", "#/-", false);
// 토큰의 갯수 반환
System.out.println(returnDelimsTokens.countTokens());
while (returnDelimsTokens.hasMoreTokens()) {
System.out.println(returnDelimsTokens.nextToken());
}
/*
※ 출력 결과
write
once
run
anywhere
*/
JVM(Java Virtual Machine)은 Java로 작성된 애플리케이션을 실행시키기 위해 반드시 필요한 가상 컴퓨터로서, Java 애플리케이션이 OS와 하드웨어에 독립적으로 실행가능하게 한다. OS와 하드웨어와의 관계가 독립적이라는 의미는 어떤 OS(Windows, Linux .. ) 라고 하더라도 해당 OS에 실행가능한 JVM만 존재한다면, Java 애플리케이션이 실행가능하다는 것이다. 단, JVM는 OS에 종속적이기 때문에 해당 OS에서 실행가능한 JVM이 필요하다.
■ Java 애플리케이션 실행 구조
예시) OS가 Windows일 경우
JVM은 Java 애플리케이션을 OS와 하드웨어에 구애받지 않고 실행가능하게 함으로써 Java 애플리케이션이 한번 작성되면 어떤 환경(OS, 하드웨어)에서든지 실행 가능하게 만들었다.
■ JVM의 메모리 구조
응용프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고, JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
■ 메서드 영역(Method Area)
인스턴스 생성을 위한 필요한 클래스 정보와 클래스 변수가 저장되는 공간이다.
각 데이터는 Runtime Constant Pool에서 Reference를 가지고 있어서
물리적 메모리 위치를 참조할 때 사용하게 된다.
■힙(Heap) 영역
인스턴스가 생성되는 공간으로 프로그램 실행 중 생성되는 모든 인스턴스가 이곳에 생성된다.
그 중에는 객체, 배열, Array 등이 있다.
인스턴스에 대한 참조가 이루어지지 않거나, 인스턴스에 사용이 종료되었을 경우에는
메모리 공간의 효율을 높이기 위해 인스턴스는 가비지 컬렉터(Garbage Collector) 에 의해 삭제된다.
예시 1) Person 클래스를 인스턴스화한 스택(Stack)영역 참조변수가
힙(Heap)공간의 인스턴스를 참조할 경우
예시 2) 스택(Stack)영역 참조변수가 힙(Heap)공간의 인스턴스를 참조하지 않을 경우
■스택(Stack) 영역(call stack 또는 execution stack)
메서드의 작업에 필요한 메모리 공간을 제공한다.
즉, 메소드가 작업을 진행하는동안 지역변수, 매게변수, 연산의 결과 등을 저장한다.
그리고 메소드의 작업이 종료되면 메모리공간은 반환되어 비워지고 메소드의 반환값은
해당 메소드를 호출한 메소드에게 전달된다.
예시) A 메소드 내부에서 B 메소드를 호출하고 B 메소드 내부에서 C 메서드를 호출했다는 가정
Stack은 후입선출(LIFO : Last In First Out) 자료구조 형식이다. 따라서 Stack의 가장 상위 메서드가 현재 실행중인 메서드이고, 그 아래 메서드가 현재 실행중인 메서드를 호출한 메서드이다.
■PC Register
PC Registers는 Thread가 생성될 때 마다 생기는 공간으로 Thread가 어떠한 명령을 실행하게 될지에 대한 부분을 기록한다.
■Native method stack
자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.
보통 C/C++등의 코드를 수행하기 위한 스택이다.
JNI(Java Native Interface)를 통해 표준에 가까운 방식으로 구현이 가능하다.