GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Java 8 Function trong Java 8

Function trong Java 8

Đăng vào 11/06/2018 . Được đăng bởi GP Coder . 23776 Lượt xem . Toàn màn hình

Nội dung

  • 1 Giới thiệu Function<T, R>
  • 2 Một số ví dụ

Giới thiệu Function<T, R>

Java 8 cung cấp sẵn cho chúng ta rất nhiều Functional Interface và Function<T, R> là một trong số đó. Cũng giống như những functional interface khác, Function<T, R> có thể sử dụng cho lambda expression hoặc method reference cho một mục đích cụ thể nào đó. Function<T,R> chỉ có một method trừu tượng duy nhất chấp nhận một tham số đầu vào, và method trả về một đối tượng khác.

Mục đích chính của Function là giúp chúng ta dễ dàng chuyển một đối tượng từ kiểu dữ liệu này sang kiểu dữ liệu khác.

Interface Function được khai báo trong package java.util.function như sau:

Trong đó:

  • R apply(T t) : là một phương thức trừu tượng có thể được sử dụng với lambda expression hoặc method reference cho một mục đích cụ thể nào đó.
  • Phương thức apply() thực hiện một hành động cụ thể trên đối số đã cho và trả về một đối khác.

Interface Function còn cung cấp một phương thức mặc định (default method) sau:

  • Function<V, R> compose(Function<? super V, ? extends T> before) : phương thức này trả về một function gộp mà nó đã áp dụng before Function lên đối số đầu vào, sau đó áp dụng function lên dữ liệu đầu ra.
  • Function<T, V> andThen(Function<? super R, ? extends V> after) : phương thức này trả về một Function gộp mà nó đã áp dụng function lên dữ liệu đầu vào và sau đó áp dụng tiếp after function lên kết quả đầu ra.
  • Function<T, T> identity() : phương thức này trả về một function luôn trả về đối số đầu vào của nó.

Một số ví dụ

Sử dụng R apply(T t)


package com.gpcoder.function;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.function.Function;

public class FunctionExample1 {

	public static void main(String[] args) {

		Function<String, Integer> numberConverter = (str) -> Integer.parseInt(str);
		System.out.println(numberConverter.apply("1")); // 1

		Function<LocalDate, String> dateConverter = (d) -> d.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
		System.out.println(dateConverter.apply(LocalDate.now())); // 27/05/2018
	}
}

Trong ví dụ trên tôi đã tạo 2 Function:

  • Function numberConverter : chấp nhận đối số đầu vào là một chuỗi (String), kết quả đầu ra là một số (Integer).
  • Function dateConverter : chấp nhận đối số đầu vào là một LocalDate, kết quả đầu ra là một chuỗi (String) của Date đã được format.

Để nhận được kết quả của Function, chúng ta cần gọi phương thức apply().

Chuyển một đối tượng này sang một đối tượng khác (object to object)


package com.gpcoder.function;

import java.util.function.Function;

class User {
	String name;
	String email;
	String password;

	public User(String name, String email, String password) {
		this.name = name;
		this.email = email;
		this.password = password;
	}
}

class Member {
	String name;
	String email;

	public Member(String name, String email) {
		this.name = name;
		this.email = email;
	}

	@Override
	public String toString() {
		return "Member [name=" + name + ", email=" + email + "]";
	}
}

public class FunctionExample2 {

	public static void main(String[] args) {

		Function<User, Member> mapUserToMember = u -> new Member(u.name, u.email);

		User user = new User("gpcoder", "gpcodervn@gmail.com", "123");
		Member member = mapUserToMember.apply(user);
		System.out.println(member);
	}
}

Output của chương trình trên:


Member [name=gpcoder, email=gpcodervn@gmail.com]

Chuyển một danh sách đối tượng này sang một danh sách đối tượng khác (list object to list object)


package com.gpcoder.function;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FunctionExample3 {

	public static void main(String[] args) {
		
		List<User> users = Arrays.asList( // 
			new User("gpcoder1", "gpcodervn1@gmail.com", "123"), //	
			new User("gpcoder2", "gpcodervn2@gmail.com", "124"), //	
			new User("gpcoder3", "gpcodervn3@gmail.com", "125") //	
		);

		Function<User, Member> mapUserToMember = u -> new Member(u.name, u.email);

	    List<Member> members = users.stream()
	    		.map(mapUserToMember)
	            .collect(Collectors.toList());
	}
}

Sử dụng phương thức mặc định andThen() và compose()

Phương thức andThen() : phương thức này trả về một Function thực hiện hai hành động theo thứ tự, trước tiên là hành động của Function mà phương thức được gọi và theo sau bởi hành động của Function được truyền vào đối số.

Phương thức compose() : phương thức này trả về một Function thực hiện hai hành động theo thứ tự, trước tiên là hành động của Function mà được truyền vào đối số và theo sau bởi hành động của Function gọi phương thức.

Phương thức identity() : phương thức này trả về một Function thực hiện trả về kết quả đúng bằng với đối số được truyền vào.


@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);
	
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
	
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
	
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

Ví dụ:


package com.gpcoder.function;

import java.util.function.Function;

public class FunctionExample4 {

	public static void main(String[] args) {

		Function<Integer, Integer> times2 = n -> n * 2;
		Function<Integer, Integer> squared = n -> n * n;

		Function<Integer, Integer> andThen = times2.andThen(squared);
		System.out.println("Using andThen: " + andThen.apply(5)); // 100

		Function<Integer, Integer> compose = times2.compose(squared);
		System.out.println("Using compose: " + compose.apply(5)); // 50
	}
}

Sử dụng Function với các lớp cho kiểu dữ liệu nguyên thủy (primitive type)

Java 8 cung cấp một số Interface Function cho các wrapper class của kiểu dữ liệu nguyên thủy như sau:

    • IntFunction : chấp nhận một đối số đầu vào kiểu int và kết quả đầu ra là kiểu bất kỳ.
    • LongFunction : chấp nhận một đối số đầu vào kiểu long và kết quả đầu ra là kiểu bất kỳ.
    • DoubleFunction : chấp nhận một đối số đầu vào kiểu double và kết quả đầu ra là kiểu bất kỳ.

@FunctionalInterface
public interface IntFunction<R> {
    R apply(int value);
}

@FunctionalInterface
public interface LongFunction<R> {
    R apply(long value);
}

@FunctionalInterface
public interface DoubleFunction<R> {
    R apply(double value);
}

Ví dụ:


package com.gpcoder.function;

import java.util.function.DoubleFunction;
import java.util.function.IntFunction;
import java.util.function.LongFunction;

public class FunctionExample5 {

	public static void main(String[] args) {

		IntFunction<String> ifunc = (x) -> Integer.toString(x * x);
		LongFunction<String> lfunc = (x) -> Long.toString(x * x);
		DoubleFunction<String> dfunc = (x) -> Double.toString(x * x);

		System.out.println(ifunc.apply(3)); // 9
		System.out.println(lfunc.apply(5)); // 25
		System.out.println(dfunc.apply(10)); // 100.0
	}
}

Sử dụng Function 2 đối số với BiFunction

Như đã nói ở phần trên Function chỉ chấp nhận 1 đối số đầu vào, để có thể sử dụng Function với 2 đối số đầu vào chúng ta sử dụng Interface BiFunction.

Về cơ bản, interface BiFunction  không khác biệt so với Function , ngoại trừ nó chấp nhận 2 đối số đầu vào.

Ví dụ:


package com.gpcoder.function;

import java.util.function.BiFunction;
import java.util.function.Function;

public class BiFunctionExample {

	public static void main(String[] args) {

		BiFunction<String, String, String> function1 = (s1, s2) -> s1 + s2;
		System.out.println(function1.apply("gpcoder", ".com")); // gpcoder.com

		BiFunction<Integer, Integer, Integer> function2 = (a, b) -> a + b;
		System.out.println(function2.apply(1, 2)); // 3

		BiFunction<Integer, Integer, Integer> times2 = (a, b) -> a + b;
		Function<Integer, Integer> squared = (n) -> n * n;

		BiFunction<Integer, Integer, Integer> andThen = times2.andThen(squared);
		System.out.println("Using andThen: " + andThen.apply(5, 2)); // 49
	}
}

Tài liệu tham khảo:

  • https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html
  • https://docs.oracle.com/javase/8/docs/api/java/util/function/BiFunction.html

 

4.6
10
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Java 8 Được gắn thẻ: Java 8

Supplier trong Java 8
Lớp Collectors trong Java 8

Có thể bạn muốn xem:

  • Biểu thức Lambda trong Java 8 – Lambda Expressions (07/05/2018)
  • Giới thiệu về Stream API trong Java 8 (14/05/2018)
  • Interface trong Java 8 – Default method và Static method (26/04/2018)
  • Predicate trong Java 8 (21/05/2018)
  • String Joiner trong Java 8 (23/07/2018)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (98056 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (97695 lượt xem)
  • Giới thiệu Design Patterns (87758 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (86427 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (83830 lượt xem)

Nội dung bài viết

  • 1 Giới thiệu Function<T, R>
  • 2 Một số ví dụ

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link