03_Exploring the Exciting New Features in Java 8

Functional Interfaces: Built-in Functionality

Functional Interface has only one abstract method using @FunctionalInterface to mark an interface as functional. built-in functional interfaces like Predicate, Function, and Supplier.

Why? Leveraging functional interfaces for improved code readability.

@FunctionalInterface
interface MyFunctionalInterface {
    void doSomething();
}

Example - Runnable Functional interfaces can be used to define tasks that can be executed concurrently. The Runnable interface is a functional interface with a single method void run(), commonly used for executing code in a separate thread.

@FunctionalInterface
interface Runnable {
    void run();
}

// Usage
Runnable task = () -> System.out.println("Executing task");
Thread thread = new Thread(task);
thread.start();

Lambdas: Simplifying Functional Programming

Lambda Function allows us to define a block of code that can be passed around and executed later.

Times each integers

// times each integers by 2
  // java 7
  List<Integer> nums = Arrays.asList(1, 2, 3);
  for (int num: nums){
      System.out.println(num*2);
  }


  // java 8
  nums.forEach(num -> {
      System.out.println(num * 2);
  });

Create Max Heap

// create max heap
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
maxHeap.add(1);
maxHeap.add(2);
maxHeap.forEach(System.out::println);

Sorting Desc

List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 6);

// Sorting in descending order using lambda function
Collections.sort(numbers, (a, b) -> b.compareTo(a));

System.out.println(numbers); // Output: [8, 6, 5, 2, 1]

Create Thread using lambda

new Thread(() -> System.out.println("this is java8")).start();

Stream API: Efficient Data Processing

Stream API support functional-style operations on streams of elements. It is process the data from a collection, does not change the original data.

In the stream api , we have two diff functions: intermediate function, terminal function.

Intermidiate function
Intermidiate function transform or filter the elements of a stream and return a new stream as the result.

  • map(Function<T, R> mapper): transforms the elements of the stream into a new type.
  • filter(Predicate<T> predicate): selects only the elements that match a given condition.
  • sorted(): orders the elements based on a given condition.
  • distinct(): eliminate duplicate elements.
  • limit(long maxSize): truncates the stream to a specified size.
  • skip(long n): skips the first n elements in the stream.

Terminal function
terminal function is an operation that produces a result or a side effect.

  • forEach(): performs an action on each elements.
  • reduce(): aggregates the elements into a single result.
  • collect(): return elements into a new collection -> list, arraylist.
  • min()/ max(): find the min/ max value in the stream.
  • count(): return the # of elements in the stream
  • anyMatch()/ allMatch() / nonMatch(): return a boolean, you will give condition, return true/false, if there any / all / none of elements match given a condition/predicate.

Examples with stream api

Example 1: find all the strings that start with “c”, make it upper case, and sort it

// res: [C4, C6]
List<String> myStreamList = Arrays.asList("a1","b2","a3","c4","c6");
var res = myStreamList.stream()
        .filter(s -> s.startsWith("c"))
        .map(String::toUpperCase)
        .sorted().toList();

System.out.println(res);

Example 2: find any strings that contains lower case

// res: [a, cBBBB, caaaa]
List<String> myStreamList1 = Arrays.asList("a","SKKKKS","OOOO","cBBBB","caaaa");
List<String> res1 = myStreamList1.stream()
        .filter(s -> s.chars().anyMatch(Character::isLowerCase))
        .toList();
System.out.println(res1);

Example 3: find any strings contains upper case

// res: [SKKKKS, OOOO, cBBBB]
List<String> myStreamList1 = Arrays.asList("a","SKKKKS","OOOO","cBBBB","caaaa");
List<String> res1 = myStreamList1.stream()
       .filter(s -> s.chars().anyMatch(Character::isUpperCase))
       .toList();
System.out.println(res1);

Example 4: find any string contains lowercase and numbers

// res: [Abc123, abc123, abc123]
List<String> myStream2  = Arrays.asList("Abc123","abc123","abd","ABC123","abc123");
List<String> res2 = myStream2.stream()
        .filter(s ->s.matches(".*\\d.*"))
        .filter(s-> s.chars().anyMatch(Character::isLowerCase))
        .toList();
System.out.println(res2);

Example 5: sum of even numbers

// res: 30
List<Integer> listNums = Arrays.asList(1,2,4,5,6,7,8,9,10);
int sumAll = listNums.stream()
       .filter(n -> n%2==0)
       .reduce(0, Integer::sum);
System.out.println(sumAll);

Example 6: find the max number

// res: 10
List<Integer> listNums = Arrays.asList(1,2,4,5,6,7,8,9,10);
int maxNum = listNums.stream().reduce(Integer::max).get();
System.out.println(maxNum);

Example 7: find if any numbers >= 5 | find all numbers >= 10


List<Integer> listNums = Arrays.asList(1,2,4,5,6,7,8,9,10);
// find any numbers >= 5, res: true
System.out.println(listNums.stream().anyMatch(n -> n>=5));
// find any numbers >= 10, res: false
System.out.println(listNums.stream().allMatch(n -> n>=10));

Optional: Handling Null Values Gracefully

Optional can avoid any nullPointerException. See the example to understand Optional easier.

  • Define BankAccount class:
class BankAccount {
    private final String accountNumber;
    private final double balance;
    private final Optional<String> password;

    public BankAccount(String accountNumber, double balance, Optional<String> password) {
        this.accountNumber = accountNumber;
        this.balance = balance;
        this.password = password;
    }

    public Optional<String> getPassword() {
        return password;
    }
}
  • Create object and getpassword
BankAccount user1 = new BankAccount("a001", 1000.0, Optional.empty());
BankAccount user2 = new BankAccount("a002", 55.0, Optional.of("password123"));
//this is your subsystem that check each users have password
Optional<String> user1Password = user1.getPassword();
if (user1Password.isPresent()) {
   String password = user1Password.get();
   System.out.println(password);
} else {
   System.out.println("user 1 does not have password");
}

Default Methods: Extending Interfaces

Date and Time API: Modernizing Date Handling

CompletableFuture: Asynchronous Programming Made Easier

Introduction to CompletableFuture

CompletableFuture used to write asynchronous, non-blocking code.
Here are some key concepts and functionalities:

  • public static CompletableFuture runAsync(Runnable runnable)
  • public static CompletableFuture runAsync(Runnable runnable, Executor executor)
  • public static CompletableFuture supplyAsync(Supplier<U> supplier)
  • public static CompletableFuture supplyAsync(Supplier<U> supplier, Executor executor)
  • public T join()
  • public T get() throws InterruptedException, ExecutionException

Advanced method: thenApply, thenRun, theAccept

Writing asynchronous and non-blocking code

Handling asynchronous tasks with CompletableFuture

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值