/** * Removes all of the elements of this collection that satisfy the given * predicate... * * @implSpec * The default implementation traverses all elements of the collection using * its {@link #iterator}. Each matching element is removed using * {@linkIterator#remove()}. If the collection's iterator does not * support removal then an {@code UnsupportedOperationException} will be * thrown on the first matching element. * * ... */defaultbooleanremoveIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);boolean removed =false;finalIterator<E> each =iterator();while (each.hasNext()) {if (filter.test(each.next())) {each.remove(); removed =true; } }return removed;}
privatestaticfinalList<String> name =List.of("park","aaron","keesun","whiteship");@TestvoidforEach() throws Exception {/** * default void forEach(Consumer<? super T> action) * - 모든 요소가 처리되거나 예외가 발생할 때까지 Iterable 각 요소에 대해 지정된 작업 수행 */name.forEach(System.out::println);}@Testvoidspliterator() throws Exception {/** * default Spliterator<E> spliterator() * - Creates a Spliterator over the elements described by this Iterable. */Spliterator<String> spliterator1 =name.spliterator();Spliterator<String> spliterator2 =spliterator1.trySplit();while(spliterator1.tryAdvance(System.out::println)); // keesun, whiteshipwhile(spliterator2.tryAdvance(System.out::println)); // park, aaron}
@Test@DisplayName("spring 으로 시작하는 수업")voidtest01() {/** * Stream<T> filter(Predicate<? super T> predicate); */List<OnlineClass> springClass =springClasses.stream().filter(oc ->oc.getTitle().startsWith("spring")).collect(Collectors.toList());Assertions.assertEquals(5,springClass.size());}
스트림 변경
@Test@DisplayName("수업 이름만 모아서 스트림 만들기")voidtest03() {/** * <R> Stream<R> map(Function<? super T, ? extends R> mapper); */springClasses.stream().map(OnlineClass::getTitle).forEach(System.out::println);}...@Test@DisplayName("두 수업 목록에 들어 있는 모든 수업 아이디")voidtest04() {/** * <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); */List<OnlineClass> allClasses =aaronEvents.stream().flatMap(Collection::stream).collect(Collectors.toList());Assertions.assertEquals(8,allClasses.size());}
스트림 생성과 제한
@Test@DisplayName("10부터 1씩 증가하는 무제한 스트림 중에서 앞에 10개 빼고 최대 10개 까지만")voidtest05() {/** * public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) * Stream<T> skip(long n); * Stream<T> limit(long maxSize); * long count(); */long count =Stream.iterate(10, i -> i +1).skip(10).limit(10).count();Assertions.assertEquals(10, count);}
스트림에 있는 데이터가 특정 조건을 만족하는지 확인
@Test@DisplayName("자바 수업 중 Test가 들어 있는 수업이 있는지 확인")voidtest06() {/** * boolean anyMatch(Predicate<? super T> predicate); * boolean allMatch(Predicate<? super T> predicate); * boolean noneMatch(Predicate<? super T> predicate); */boolean result =javaClasses.stream().anyMatch(oc ->oc.getTitle().contains("Test"));Assertions.assertTrue(result);}
LocalDateTime.of(int, Month, int, int, int, int): 로컬 특정 일시
ZonedDateTime.of(int, Month, int, int, int, int, ZoneId): 특정 Zone 의 특정 일시
LocalDateTime now =LocalDateTime.now(); // 현재 시스템 Zone 일시System.out.println(now); // 2023-09-30T21:57:26.029797LocalDateTime today =LocalDateTime.of(20023,Month.SEPTEMBER,30,0,0,0,0);System.out.println(today); // +20023-09-30T00:00ZonedDateTime nowInLosAngeles =ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));System.out.println(nowInLosAngeles); // 2023-09-30T05:57:26.033318-07:00[America/Los_Angeles]Instant instant =Instant.now();ZonedDateTime zonedDateTime =instant.atZone(ZoneId.of("America/Los_Angeles"));System.out.println(zonedDateTime); // 2023-09-30T05:57:26.034100-07:00[America/Los_Angeles]
날짜 연산
LocalDateTime now =LocalDateTime.now();LocalDateTime plusDay =now.plus(10,ChronoUnit.DAYS);LocalDateTime plusMonth =now.plus(2,ChronoUnit.MONTHS);
기간 표현
// Machine Time DurationInstant now =Instant.now();Instant plus =now.plus(10,ChronoUnit.SECONDS);Duration between =Duration.between(now, plus);System.out.println(between.getSeconds()); // 10// Human Time PeriodLocalDate today =LocalDate.now();LocalDate christmas =LocalDate.of(2023,Month.DECEMBER,25);Period period =Period.between(today, christmas);System.out.println(period.getMonths()); // 2Period until =today.until(christmas);System.out.println(until.getDays()); // 25
/** * ExecutorService * * void shutdown(): 이전에 제출된 작업이 실행되지만 새 작업은 허용되지 않는 순차적 종료(Graceful Shutdown) * List<Runnable> shutdownNow(): 현재 실행 중인 모든 작업을 중지하려고 시도하고, 대기 중인 작업의 처리를 중지하고, 실행 대기 중인 작업 목록을 반환 */ExecutorService executorService =Executors.newSingleThreadExecutor();executorService.submit(() ->System.out.println("Thread "+Thread.currentThread().getName()));executorService.shutdown();/** * ScheduledExecutorService.schedule */ScheduledExecutorService executorService =Executors.newSingleThreadScheduledExecutor();executorService.schedule(() ->System.out.println("Thread "+Thread.currentThread().getName()),5,TimeUnit.SECONDS);executorService.shutdown();.../** * ScheduledExecutorService.scheduleAtFixedRate */ScheduledExecutorService executorService =Executors.newSingleThreadScheduledExecutor();executorService.scheduleAtFixedRate(() ->System.out.println("Thread "+Thread.currentThread().getName()),1,2,TimeUnit.SECONDS);
/** * V get(): 결과 가져오기 * * - Blocking Call: 값을 가져올 때까지 대기 * - timeout(최대 대기 시간) 설정 가능 */future.get();/** * boolean isDone(): 작업 상태 확인 */boolean isDone =future.isDone());/** * boolean cancel(boolean mayInterruptIfRunning): 진행중인 작업을 interrupt 요청으로 종료 * - parameter * - true: 현재 진행중인 쓰레드를 interrupt * - false: 현재 진행중인 작업이 끝날때까지 대기 * - 취소 했으면 true 못 했으면 false 리턴 * - 취소 이후에 get() 요청 시 CancellationException 발생 */boolean cancel =future.cancel(true);/** * <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) * - 동시에 실행(가장 오래 걸리는 작업 만큼 시간 소요) */List<Future<String>> futures =executorService.invokeAll(Arrays.asList(hello, the, java));/** * <T> T invokeAny(Collection<? extends Callable<T>> tasks) * - Blocking Call * - 동시 실행 작업 중 가장 짧게 소요되는 작업 만큼 시간 소요 */String result =executorService.invokeAny(Arrays.asList(hello, the, java));
/** * CompletableFuture * - 외부에서 Complete 울 명시적으로 시킬 수 있음 * - Executor 를 만들어서 사용할 필요가 없음 */CompletableFuture<String> future =newCompletableFuture<>();future.complete("aaron"); // 특정 시간 이내에 응답이 없으면 기본 값으로 리턴하도록 설정 가능/** * public T get() throws InterruptedException, ExecutionException: 결과 반환 * public T join(): get() 과 동일하지만 Unchecked Exception */System.out.println(future.get());.../** * runAsync(): 리턴값이 없는 비동기 작업 */CompletableFuture<Void> future =CompletableFuture.runAsync(() ->System.out.println("Hello "+Thread.currentThread().getName()));future.get();.../** * supplyAsync(): 리턴값이 있는 비동기 작업 */CompletableFuture<String> future =CompletableFuture.supplyAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());return"Hello";});System.out.println(future.get());
/** * public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) * - 리턴값을 받아서 다른 값으로 바꾸고 리턴하는 콜백 */CompletableFuture<String> future =CompletableFuture.supplyAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());return"Hello";}).thenApply(s ->s.toUpperCase());System.out.println(future.get()); // HELLO.../** * public CompletableFuture<Void> thenAccept(Consumer<? super T> action) * - 리턴값으로 또 다른 작업을 처리하고 리턴이 없는 콜백 */CompletableFuture<Void> future =CompletableFuture.supplyAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());return"Hello";}).thenAccept(s -> {System.out.println(s.toUpperCase());});future.get(); // HELLO.../** * public CompletableFuture<Void> thenRun(Runnable action) * - 리턴값을 받지 않고 다른 작업을 처리하는 콜백 */CompletableFuture<Void> future =CompletableFuture.runAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());}).thenRun(() -> {System.out.println(Thread.currentThread().getName());});future.get();.../** * 원하는 Executor(thread-pool)를 사용해서 실행 가능 * - default: ForkJoinPool.commonPool() */ExecutorService executorService =Executors.newFixedThreadPool(4);CompletableFuture<Void> future =CompletableFuture.runAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());}, executorService).thenRunAsync(() -> {System.out.println(Thread.currentThread().getName());}, executorService);future.get(); // pool-1-thread-2executorService.shutdown();
/** * public <U> CompletableFuture<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn) * - 연관이 있는 두 작업이 서로 이어서 실행하도록 조합 */CompletableFuture<String> hello =CompletableFuture.supplyAsync(() -> {System.out.println("Hello "+Thread.currentThread().getName());return"Hello";});CompletableFuture<String> future =hello.thenCompose(CombinationTestApp::getWorld);System.out.println(future.get());privatestaticCompletableFuture<String>getWorld(String message) {returnCompletableFuture.supplyAsync(() -> {System.out.println("World "+Thread.currentThread().getName());return message +" World"; });}.../** * public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn) * - 연관이 없는 두 작업을 독립적으로 실행하고 두 작업이 모두 종료되었을 때 콜백 실행 */CompletableFuture<String> future =hello.thenCombine(world, (h, w) -> h +" "+ w);.../** * public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) * - 여러 작업을 모두 실행하고 모든 작업 결과에 콜백 실행 */CompletableFuture[] futures = {hello, world};CompletableFuture<List<Object>> results =CompletableFuture.allOf(futures).thenApply(v ->Arrays.stream(futures).map(CompletableFuture::join).collect(Collectors.toList()));results.get().forEach(System.out::println);.../** * public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) * - 여러 작업 중에 가장 빨리 종료된 하나의 결과에 콜백 실행 */CompletableFuture<Void> future =CompletableFuture.anyOf(hello, world).thenAccept(System.out::println);future.get();}
/** * Class 인스턴스 생성하기 */Class<Ball> ballClass =Ball.class;// ballClass.newInstance(); -> deprecatedConstructor<Ball> constructor =ballClass.getConstructor(String.class);// 생성자로 인스턴스 생성Ball ball =constructor.newInstance("myBall");System.out.println(ball);/** * Class Field 수정하기 */Field field =Ball.class.getDeclaredField("A");// public static 은 특정 인스턴스에 해당하는 값이 아니라서 클래스 값에 해당하므로 인스턴스를 전달할 필요가 없음System.out.println(field.get(null));field.set(null,"newA");System.out.println(field.get(null));/** * Instance Field 수정하기 */Field field =Ball.class.getDeclaredField("b");field.setAccessible(true); // private 필드 접근을 위한 설정// 특정 인스턴스가 가지고 있는 값을 가져와야 하므로 인스턴스 필요System.out.println(field.get(ball));field.set(ball,"newB");System.out.println(field.get(ball));/** * Private Method 실행 */Method method =Ball.class.getDeclaredMethod("c");method.setAccessible(true);method.invoke(ball);/** * Public Method 실행 */Method method =Ball.class.getDeclaredMethod("sum",int.class,int.class);int invoke = (int) method.invoke(ball,1,2);System.out.println(invoke);