java.util
。Java에서 기본적으로 제공하는 Package로서Stack,Queue등의 다양한Collection, 배열에 대한 처리 , 날짜 및 시간 ,RandomClass 등을 제공하는 package
UUID( Universally Unique Identifier )
import java.util.UUID;
。128bit크기의 고유 식별자
▶-로 구분된 5개 그룹의 총 36자리(8-4-4-4-12구조 ) 문자열로 구성.
。xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M:UUID Version(4: Random 기반을 의미. )
N:UUID변형값 (8 , 9 , a , b중 하나. )
UUID.randomUUID():
。UUID를 Random으로 생성하는 Method.
▶SecureRandom을 사용하여 난수를 기반으로 생성.
▶ 중복될 가능성이 거의 없으므로 , 유일한 ID를 생성시 활용.
Scanner:import java.util.Scanner
。다양한Source로부터의 입력을 읽기위한 Class
。키보드에서 입력이 발생한 즉시 한 문자씩Buffer로 전송
▶Buffer가 가득차거나띄어쓰기또는개행문자( ex .\n)을 접하면 그전까지Buffer의 내용을 한번에 전달.
java.io.BufferedReader와 차이
。Scanner의 경우띄어쓰기와개행문자를 경계로 하여 입력값을 인식
▶BufferedReader는 오직개행문자를 경계로 인식
。Scanner의 경우스캐너객체.nextInt()등을 통해 다양한 type의 입력값을 받을 수 있다.
▶BufferedReader는BufferedReader객체.readlLine()을 통해 오직String만 입력받을 수 있다.
▶int를 받을 경우Interger.parseInt()로 형변환 수행
。입력값이 많으면BufferReader가 유리하며 처리속도가 더 빠르다.
▶Scanner의Buffer Size = 1024 char
▶BufferedReader의Buffer Size = 8192 char
Scanner객체 생성
new Scanner(standard input stream)
。Scanner객체 생성하여scanner객체.close()가 실행될때까지 콘솔에서InputStream으로부터 input을 받는 역할을 수행
ex )Scanner scanner = new Scanner(System.in);
Scannermethod
。nextBoolean()/nextByte()/nextShort()/nextInt()/nextLong()/nextFloat()/nextDouble()/next()/nextLine()이 존재
scanner객체.next()
。공백 , 줄바꿈문자로 구분된 문자열을 문자열변수로 전달
scanner객체.nextLine()
。Scanner객체에서 입력된 문자열 1줄을 문자열변수로 전달
scanner객체.nextInt()
。Scanner객체에서 입력된 정수를 정수변수로 전달
。[-2147483648,+2147483648]까지의 정수값을 받을 수 있음.Scanner scanner = new Scanner(System.in); System.out.print("이름을 입력하세요: "); String name = scanner.nextLine(); System.out.print("나이를 입력하세요: "); int age = scanner.nextInt();▶
scanner객체.close()가 도출될때까지 다음 입력을 받도록 유도
scanner객체.close()
。실행되고있는Scanner객체를 종료
Random:java.util.Random
。일련의 의사난수를 생성하는 용도의 Class
。의사난수 : 난수처럼 보이지만 컴퓨터의 특정 규칙에 따라seed를 기반으로 고정적으로 생성되는 난수
▶ 의사난수를 기반으로 난수 생성 시 생성된 값을 예측가능하지만, 진짜난수를 기반으로 난수 생성 시 예측 불가능
Random객체 생성
Random rand = new Random(seed):
。Random객체는 특정 48비트의seed를 기반으로 생성되며, 해당seed를 기반으로 난수가 생성됨.
Random method
。nextBoolean()/nextByte()/nextShort()/nextInt()/nextLong()/nextFloat()/nextDouble()/next()/nextLine()을 통해 생성됨.
ex)rand객체.nextInt(n-1):0 ~ n-1까지의 정수를 난수로 생성.
Arrays:java.util.Arrays
。배열을 정렬, 검색, 복사, 출력 시 유용한static method를 제공
Arrays의static method
Arrays.asList(배열객체):
。배열객체(int[]등 )를List<T> instance(List<Integer>등 )로 변환.
Arrays.stream(배열객체):
。배열객체(int[]등 )를Stream instance로 변환.
Arrays.equals(배열객체1,배열객체2)
。두 배열이 동일한 지 판별후boolean을 returnint[] arr1 = {1, 2, 3}; int[] arr2 = {1, 2, 3}; int[] arr3 = {3, 2, 1}; System.out.println(Arrays.equals(arr1, arr2)); // true System.out.println(Arrays.equals(arr1, arr3)); // false (순서 다름).
Arrays.copyOf(배열,복사할요소수)
。배열을 복사int[] original = {1, 2, 3}; int[] copy1 = Arrays.copyOf(original, 3); // 그대로 복사 int[] copy2 = Arrays.copyOf(original, 5); // 길이 늘리면 나머지는 0 System.out.println(Arrays.toString(copy1)); // [1, 2, 3] System.out.println(Arrays.toString(copy2)); // [1, 2, 3, 0, 0].
Arrays.fill(배열객체,시작인덱스,끝인덱스, 채울값)
。배열의 요소를 특정 값으로 값을 채우는 역할을 수행int[] numbers = new int[5]; Arrays.fill(numbers, 7); System.out.println(Arrays.toString(numbers)); // [7, 7, 7, 7, 7] Arrays.fill(numbers, 1, 4, 9); System.out.println(Arrays.toString(numbers)); // [7, 9, 9, 9, 7].
Arrays.toString(배열객체):
。배열객체를[ 요소1, 요소2 , ... ]의 문자열로 변환 후 return
。1차원 배열에만 사용가능.int[] a = {1,2,3,4,5}; String b = Arrays.toString(a); System.out.println(b); // b=[1, 2, 3, 4, 5]로 반환.
Arrays.deepToString(2차원배열객체)
。2차원 배열객체(int[][])를[ [요소1], [요소2] , ... ]의 문자열로 변환 후 returnint[][] matrix = {{1, 2}, {3, 4}}; System.out.println(Arrays.deepToString(matrix)); // 출력: [[1, 2], [3, 4]].
Arrays.binarySearch( 배열, 검색Key)
。배열에서 이진검색을 수행하는 Method.
。같은 Method의 동일한 명으로Method Overloading처리되어있어 배열요소의 자료형과 관계없이 Method 사용이 가능
。검색성공 시key와 일치하는 배열요소의index를 반환
。검색에 실패한 경우 배열 내 key값이 위치해야할 index의-index -1를 반환.
▶ index : 5에 위치가 예상될 경우-5 -1=-6을 반환int[] a = {1,2,3,4,5,7,8,9}; int key = 5; int predict = Arrays.binarySearch(a,key); if ( predict < 0 ){ // 배열 내 없는 경우 System.out.println((( predict+1) * (-1) )); // 위치해야할 index 번호 } else{ // 배열 내 존재 시 System.out.println(predict); }
static int binarySearch(형식[] a, 형식 key)
。자연정렬( natural ordering )된 배열에서 요소와 key 간 대소관계를 판단하여 Key에 해당하는 요소를 검색하는 method.
▶int[],string[]에서 검색 시 적당
static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
。자연정렬이 아닌 순서로 나열된 배열에서 검색하는 method.
▶ 자연정렬을 논리적으로 갖지 않는 클래스의 배열에서 검색할때 적당.자연정렬 ( Natural Ordering )
。인간친화적인 방식으로 데이터를 정렬
▶ 숫자문자열을 숫자로 인식하여 정렬을 수행
。 컴퓨터정렬(lexicographical sort)의 경우 숫자의 문자열을ASCII의 코드값을 기반으로 정렬을 수행.
ex )"1" , "2" , "10"의 문자열을 정렬 시
。자연정렬 :"1", "2", "10"
。컴퓨터정렬 : "1", "10", "2" ▶ASCII기준
Arrays.sort(배열)orArrays.sort( 배열, int fromidx, int toidx)
。Quick Sort또는Merge Sort알고리즘을 기반으로 1차원 배열을 오름차순정렬
▶ 기본 자료형배열의 정렬 시Quick Sort/ 클래스 객체배열의 정렬 시Merge Sort
。fromidx = toidx: 정렬범위 0
。fromidx > toidx:IllegalArugmentException발생
。fromidx < 0ortoidx > 배열길이:ArrayIndexOutOfBoundsException발생
▶ 동일 Method의 동일한 명으로Method Overloading처리되어있어 배열요소의 자료형과 관계없이 Method 사용이 가능
- 기본 자료형 배열( ex
int[])의 정렬
Arrays.sort(자료형배열)
。Quick Sort알고리즘을 기반으로 기본 자료형 배열을 오름차순정렬
▶ 불안정정렬로서 동일 값 사이 순서가 바뀔 수 있음int[] a = { 1,3,6,3,2,1,3,4 }; Arrays.sort(a);▶ 단순하게
Arrays.sort(배열)을 선언하는것으로 정렬됨
- 클래스 객체 배열( ex
Person[])의 정렬
Comparable의 경우 :Arrays.sort(객체배열)
Comparator의 경우Arrays.sort(객체배열, Comparator객체)
。Merge Sort알고리즘을 기반으로 배열을 오름차순정렬
▶ 안정정렬로서 동일값 간 순서가 변화하지는 않는다.
。Comparable<T>또는Comparator<T>를 활용하여TClass의 instance의 정렬을 수행.
Comparable<T>을 활용한 객체배열정렬
。정렬할instance가 속하는Class에Comparable<T>와 구현메소드compareTo(T o)를 상속 후Arrays.sort(객체배열)사용
。단일field를 기준으로 정렬할 경우 활용.class Person implements Comparable<Person> { String name; int age; public Person(String name, int age){ this.age = age; this.name = name; } public int compareTo(Person o){ return this.age - o.age; } } class Main{ public static void main(String[] args) { Person[] pg = new Person[]{ new Person("lee",26), new Person("kim",24), new Person("go",28), }; Arrays.sort(pg); } }
Comparator<T>을 활용한 객체배열정렬
。Comparator<T>및compare(T o1, T o2)를 상속 및 구현하여 특정field를 기반으로 정렬을 수행하는Comparator생성
。다양한field를 기준으로 정렬이 필요할 경우 각각 담당하는Comparator를 구현class Person{ String name; int age; public Person(String name, int age){ this.age = age; this.name = name; } } // Person[]를 name field 기반 정렬 시 활용 class NameComparator implements Comparator<Person>{ public int compare(Person p1, Person p2){ return p1.name.compareTo(p2.name); } } // Person[]를 age field 기반 정렬 시 활용 class AgeComparator implements Comparator<Person>{ public int compare(Person p1, Person p2){ return p1.age - p2.age; } } class Main{ public static void main(String[] args) { Person[] pg = new Person[]{ new Person("lee",26), new Person("kim",24), new Person("go",28), }; Arrays.sort(pg, new NameComparator()); for(Person p : pg){ System.out.print(p.name+" "); } Arrays.sort(pg, new AgeComparator()); for(Person p : pg){ System.out.print(p.age+" "); } } }
StringTokenizer:java.util.StringTokenizer
。String을 특정Delimiter기준으로 분할하여Token단위로 분리하는Class
new StringTokenizer(String객체, "구분자")
StringTokenizer객체.nextToken()
。StringTokenizer 객체의문자열을Delimiter기준으로 분할한문자열을 순차적으로 가져오는 역할을 수행.
Optional<T>:java.util.Optional
。JAVA 8에서 등장하여NPE발생을 사전에 방지하고자Null이 올 수 있는 값을 감싸는Wrapper 클래스
▶Null인 값이 왔을때 대응을메소드로 정의
。Generic에는Optional 객체가 어느Type의데이터를 저장해야 하는지 제약하여타입안전성확보
▶ 정의를 안하는 경우get()호출 시Object Type으로 반환
。Spring JPA에서 주로 활용하는 type으로Repository객체를 통해CRUD를 수행 시Optional 객체로 반환
NPE(NullPointerException) :
。현업에서개발시 가장 많이 발생하는예외
▶Optional<T>를 통해 방지
Optional 객체생성하는static메소드
ex )Optional<Integer> i = Optional.ofNullable(1)
Optional.empty()
。값이 없는Optional 객체생성
Optional.of(데이터)
。Optional로 감쌀데이터가 절대Null이 아닌 경우Optional 객체를 생성하는메소드
▶Optional.of(Null데이터)을 수행 시NPE발생
Optional.ofNullable(데이터)
。Optional로 감쌀데이터에Null이거나 아닐 수 있는 경우Optional 객체를 생성하는메소드
▶null인 경우Optional.empty()로 변환
Optional인스턴스 메소드
。Optional 객체의데이터가null일 경우 실행하는인스턴스메소드에 전달하는람다식은매개변수가 없도록 정의
▶null이 아닌경우의메소드의람다식은매개변수를 정의
Optional객체.get()
。Optional객체의데이터를 return
▶Generic이 명시가 안된 경우Object로 반환
。Optional객체.getAsInt()등의 메소드 존재
。Optional.empty() 객체에get을 수행하는 경우NoSuchElementException발생
▶ 반드시Optional 객체가Null이 없을때를 보장하는 상황에서만 사용하며Optional 객체가Null이 포함될 수 있는 가능성이 있는 경우orElse()를 통해 안전성을 확보
Optional객체.isPresent()
。Optional객체의 데이터의 존재여부를boolean으로 return
Optional객체.orElseGet(람다식):
。Optional객체의 데이터가null인 경우람다식을 활용해특정값으로 반환
▶객체의 데이터가null이므로람다식 매개변수를 정의하지 않는다.
Optional객체.orElse(변수)
。Optional객체의 데이터가Null인 경우 매개변수에 입력된특정값을 반환Optional<SomeClass> op1 = Optional.of(null); SomeClass output1 = op1.orElseGet(() -> new SomeClass(1)); SomeClass output2 = op1.orElse(new SomeClass(1));
Optional객체.ifPresent(람다식)
。Optional객체의 데이터를 포함하는 경우람다식을 수행하며Null인 경우 실행되지 않음
▶Optional객체의 데이터가 존재하므로람다식 매개변수를 정의하여Optional객체의 데이터를 전달
。void로서반환값이 없음Optional<SomeClass> op = Optional.of(new SomeClass(1)); op.ifPresent((obj)->{ System.out.println(obj.age); // 1 출력 });
Optional객체.ifPresentOrElse( null 아닌 경우 람다식 , null인 경우 람다식 ):
。Optional 객체의데이터가null이 아닌 경우와null인 경우 실행할람다식을 모두 정의하여 2가지 경우를 모두 대응
。Optional 객체의데이터가 존재하는람다식은매개변수를 정의하고 존재하지 않는람다식은매개변수를 정의하지 않는다.
。void로서반환값이 없음Optional<SomeClass> op1 = Optional.ofNullable(null); op1.ifPresentOrElse((obj)->{ System.out.println(obj.age); } , ()->{ System.out.println("null"); // null 출력 });
Optional객체.orElseThrow(람다식)
。Optional 객체의데이터가Null인 경우람다식을 통해Exception 객체를 return하여예외를throw
▶ 현업에서 제일 많이 사용하는 경우
。매개변수에 정의하는람다식은Exception 객체를 생성하여 return하도록 정의
▶생성자참조를 통해람다식을 축약할 수 있음
▶Throwable 인터페이스( = 최상위 부모 )를 구현하는Exception 클래스 객체를 생성하여 return 하도록 설정
。void로서반환값이 없음Optional<SomeClass> op1 = Optional.ofNullable(null); op1.orElseThrow(()->{ return new IllegalArgumentException(); }); // IllegalArgumentException 발생// 생성자참조로 람다식 축약 Optional<SomeClass> op1 = Optional.ofNullable(null); op1.orElseThrow(IllegalArgumentException::new);
Concurrent:java.util.concurrent
。JAVA에서동시성( Concurrency ) 프로그래밍을 지원하기위한 패키지
▶멀티스레드환경에서 안전하고 효율적인 작업 수행가능.
Atomic:java.util.concurrent.atomic
。멀티스레드환경에서명령어를 단일CPU Clock내원자적으로 처리할 수 있도록 하여데이터 불일치로부터 안전하게 값을 처리할 수 있도록 도와주는클래스
▶동기화없이도 안전하게 사용
。복수의스레드가공유자원에 대해Concurrent하게 작용하여Race Condition이 발생할 수 있는 경우 활용
。원자성을 보장하여인터럽트없이 단일 동작으로 수행
AtomicBoolean:java.util.concurrent.atomic.AtomicBoolean
。멀티스레드환경에서boolean을원자적으로 처리할 수 있도록하는클래스
▶boolean값을동기화없이도 안전하게 사용가능.
AtomicBoolean메서드
AtomicBoolean객체.get()
。현재 객체의Boolean값을 반환
AtomicBoolean객체.set(boolean)
。현재 객체의Boolean값을 설정
ExecutorService:java.util.concurrent.ExecutorService
。자바의비동기 처리에 관한Business Logic을 제공하는동시성 API
▶스레드 풀( Thread Pool )의스레드 생명주기를 관리하면서스레드의작업을 실행
。java.util.concurrent.Executors 클래스의static factory method를 통해스레드풀 객체를 통해 선언
ExecutorService es = Executors.newFixedThreadPool(5);
▶ 최대 5개까지의스레드를 할당받는ExecutorService 객체생성
。생성된ExecutorService 객체는CompletableFuture를 통한비동기 처리에 활용
。해당ExecutorService등을 통한비동기 처리는Spring에서 더 쉽게 구현이 가능하므로 더 이상 사용하지않는다.
▶Spring Webflux의Reactive Java에서비동기 처리의 개념을 학습하기위한 용도로 활용// Executors의 팩토리메서드를 통해 5개의 스레드를 갖는 스레드풀 객체 생성 후 // ExecutorService 객체로 선언 ExecutorService es = Executors.newFixedThreadPool(5); // 해당 ExecutorService 객체로 비동기 작업 수행 후 // 결과를 CompletableFuture객체로 Wrapping하여 반환 var c1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); // 2초 대기 후 반환 } catch (InterruptedException e) { } return 20; }, es); var c2 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(4000); // 4초 대기 후 반환 } catch (InterruptedException e) { } return 40; }, es); // 결과로 도출된 2개의 CompletableFuture객체의 연산 결과를 Wrapping하여 반환 var c3 = c1.thenCombine(c2, (x, y) -> x + y); var c4 = c1.thenCombine(c2, (x, y) -> x * y); System.out.println(c3.join()); // c2의 결과가 도출되는 4초 후 다음 구문이 수행 // 60 출력 try { System.out.println(c4.get()); // 800 출력 } catch (Exception e) {}。
System.out.println(c3.join());에서 실제 작업이 수행되며 그 이전까지는비동기의콜백을 등록한 것으로서 실제 작업이 수행되지는 않음.
Executors:java.util.concurrent.Executors
。Executor,ExecutorService과 같은동시성 API에서 사용되는스레드풀 객체등 을 생성하는Factory Method를 포함하는유틸리티 클래스
▶동시성 API를 보조
newFixedThreadPool( 생성할 스레드 수 )
。매개변수로 전달한고정 크기의스레드를 유지하는스레드풀 객체를 생성
▶Task수행 시 설정된스레드 수까지스레드들을 생성하여 수행 및 그 이상은LinkedBlockingQueue에 대기
CompletableFuturejava.util.concurrent.CompletableFuture
。비동기 작업에 대한결과값을 감싸서 받을 수 있는클래스
▶비동기 결과값을 포함하는Wrapper Class
▶비동기처리를 위한Non-Blocking Callback Chain을 구성할 수 있음.
。몇초 이내응답이 오지않으면 기본값을 반환하는타임아웃기능이 존재
static method
CompletableFuture.supplyAsync(람다식 , ExecutorService객체)
。내부람다식을 통해비동기적으로 값을 생성하는Supplier작업을 실행 후 결과값을CompletableFuture<T> 객체로Wrapping하여 return하는static Factory Method
▶비동기적으로 작동하므로, 내부 연산이 끝날때까지 값을 반환하지 않고 끝난 경우 값을 반환
ex )Thread.sleep(ms)를 통해 연산 대기 시 해당 대기시간이 끝난 후 결과를 반환
instance method
CompletableFuture객체1.thenCombine( CompletableFuture객체2 , 람다식)
。두개의CompletableFuture 객체의 결과값들을람다식을 통한 연산의결과값을 합성한 값을 통해 새로운CompletableFuture객체를 생성
▶람다식은함수형 인터페이스를 반환하며 이는메소드 참조로Integer::sum등이 올 수 있다.
。두객체중 하나라도Exception발생 시CompletionException발생CompletableFuture<Integer> a = CompletableFuture.supplyAsync(() -> 2); CompletableFuture<Integer> b = CompletableFuture.supplyAsync(() -> 3); CompletableFuture<Integer> product = a.thenCombine(b, (x, y) -> x * y);
CompletableFuture객체.get():
。CompletableFuture의 결과값을 반환
。작업 도중Exception발생 시ExecutionException,인터럽트발생 시InterruptedException발생
▶ 반드시try ~ catch를 사용하여 값 인가.
CompletableFuture객체.join()
。CompletableFuture의 결과값을 반환
▶get()과 달리Exception이 발생하지 않으므로try ~ catch를 사용하지않아도됨.