使用Java 8的二元函数BiFunction,采用函数式编程思维实现List元素的自定义排序功能

简介: 使用Java 8的二元函数BiFunction,采用函数式编程思维实现List元素的自定义排序功能
package java8;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
class Article {
  private String author;
  private String tag;
  private int rank;
  public Article(String _author, String _tag, int _rank) {
    this.author = _author;
    this.tag = _tag;
    this.rank = _rank;
  }
  @Override
  public String toString() {
    return String.format("Article author: " + this.author + " tag: "
        + this.tag + " rank: " + this.rank);
  }
  public String getAuthor() {
    return this.author;
  }
  public String getTag() {
    return this.tag;
  }
  public int getRank() {
    return this.rank;
  }
}
/*
 * Jerry 2016-01-21 12:24PM Function signature This is a functional interface
 * whose functional method is apply(Object).
 * 
 * Parameters: <T> the type of the input to the function <R> the type of the
 * result of the function Since: 1.8
 */
@SuppressWarnings("unused")
public class FunctionCombine {
  private static List<Article> getTestData() {
    ArrayList<Article> data = new ArrayList<Article>();
    data.add(new Article("Jerry", "ABAP", 1));
    data.add(new Article("Jerry", "Scala", 3));
    data.add(new Article("Jerry", "JavaScript", 2));
    data.add(new Article("Orlando", "Swift", 4));
    return data;
  }
  /*
   * Jerry 2016-01-21 12:58PM be careful about this syntax: ? is necessary
   * 如果用了::, 前面就不应该用lamda
   */
  private static void printList(List<? extends Object> list) {
    list.forEach(a -> {
      System.out.println("list item: " + a);
    });
    /*
     * cannot insert any new element except null The method add(capture#2-of
     * ? extends Object) in the type List<capture#2-of ? extends Object> is
     * not applicable for the arguments (String) list.add("1");
     */
  }
  private static void insertList(List<? super Number> list) {
    // can insert
    list.add(1.2f);
    list.add(1);
  }
  private static void superTest() {
    ArrayList<Number> a = new ArrayList<Number>();
    insertList(a);
    printList(a);
  }
  public static void combineTest() {
    Function<Integer, Integer> times2 = e -> e * 2;
    Function<Integer, Integer> squared = e -> e * e;
    // 先执行参数,再执行调用者
    /*
     * 1. 4 * 4 = 16 16 * 2 = 32
     */
    System.out.println("result: " + times2.compose(squared).apply(4)); // 32
    /*
     * 先执行调用者: 4 * 2 = 8 再执行then传入的function 8 * 8 = 64
     */
    System.out.println("result: " + times2.andThen(squared).apply(4)); // 64
  }
  /*
   * use this way to get a stream: Stream<Person> people = Stream.of(new
   * Person("Paul", 24), new Person("Mark", 30), new Person("Will", 28)); 由于
   * BiFunction 接收两个参数,它只提供 andThen 函数。你不能将一个函数的结果放在一个接收两个参数的函数中,因此没有 compose
   * 函数。
   */
  public static void articleTest() {
    Object object = Collectors.toList();
    // 输入参数为String和List<Article>,输出为根据name属性进行排序后的新List
    BiFunction<String, List<Article>, List<Article>> byAuthor = (name,
        articles) -> articles.stream()
        .filter(a -> a.getAuthor().equals(name))
        .collect(Collectors.toList());
    BiFunction<String, List<Article>, List<Article>> byTag = (tag, articles) -> articles
        .stream().filter(a -> a.getTag().equals(tag))
        .collect(Collectors.toList());
    List<Article> result = byAuthor.apply("Jerry", getTestData());
    System.out.println("Jerry's book");
    printList(result);
    // Jerry 2016-01-21 13:47PM - comparator需要返回一个int
    Function<List<Article>, List<Article>> sortByRank =
    articles -> articles.stream()
        .sorted((x, y) -> y.getRank() - x.getRank())
        .collect(Collectors.toList());
    List<Article> Rankresult = sortByRank.apply(getTestData());
    System.out.println("rank sort result");
    printList(Rankresult);
    Function<List<Article>, Optional<Article>> first = a -> a.stream().findFirst();
    // 先sort,再返回头一个元素
    Function<List<Article>, Optional<Article>> top = first.compose(sortByRank);
    Optional<Article> topArticle = top.apply(getTestData());
    System.out.println("top article: " + topArticle);
    // find Jerry's top article:
    // 接受两个输入,author和list本身
    BiFunction<String, List<Article>, Optional<Article>> topByAuthor =  
          byAuthor.andThen(sortByRank).andThen(first);
    System.out.println("Jerry's top article: " + topByAuthor.apply("Jerry", getTestData()).get());
  }
  public static void main(String[] args) {
    articleTest();
    // superTest();
  }
}

输出:

Jerry's book
list item: Article author: Jerry tag: ABAP rank: 1
list item: Article author: Jerry tag: Scala rank: 3
list item: Article author: Jerry tag: JavaScript rank: 2
rank sort result
list item: Article author: Orlando tag: Swift rank: 4
list item: Article author: Jerry tag: Scala rank: 3
list item: Article author: Jerry tag: JavaScript rank: 2
list item: Article author: Jerry tag: ABAP rank: 1
top article: Optional[Article author: Orlando tag: Swift rank: 4]
Jerry's top article: Article author: Jerry tag: Scala rank: 3
相关文章
|
1月前
|
运维 监控 JavaScript
JAVA村卫生室、诊所云HIS系统源码 支持医保功能
运维运营分系统 1、系统运维:环境管理、应用管理、菜单管理、接口管理、任务管理、配置管理 2、综合监管:统计监管的医疗机构的综合信息,包括医疗业务量、人员配备量、支付分类占比等。 3、系统运营:机构管理、药品目录管理、用户管理、角色管理、字典管理、模板管理、消息管理、运营配置、售后服务、外部系统。
30 0
|
1月前
|
JavaScript 前端开发 Java
Java Script中的函数原型是什么
Java Script中的函数原型是什么
11 0
|
1月前
|
Java Spring 容器
【Java】Spring如何扫描自定义的注解?
【Java】Spring如何扫描自定义的注解?
35 0
|
28天前
|
Java
java8中List对象转另一个List对象
java8中List对象转另一个List对象
37 0
|
1天前
|
Java API
java流式实现chatGPT会话功能
java流式实现chatGPT会话功能
8 1
|
14天前
|
Java
Java配置大揭秘:读取自定义配置文件的绝佳指南
Java配置大揭秘:读取自定义配置文件的绝佳指南
16 0
Java配置大揭秘:读取自定义配置文件的绝佳指南
|
18天前
|
NoSQL Java Redis
Java自定义线程池的使用
Java自定义线程池的使用
|
1月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
94 3
|
1月前
|
Java
java 自定义注解 实现限流
java 自定义注解 实现限流
11 1