关于函数对象,百度百科对它是这样定义的:

重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。又称仿函数

听起来确实很难懂,通过搜索我找到一篇博客,作者对其是这样的描述:

如果把对象理解成指针的话,也就是说,函数对象其实就是函数指针的概念。

这是该作者通过类比法比较出来的:

我们常说java没有指针,其实java中的对象引用就是指针,有时候我们说一个对象往往指的就是这个对象的引用,也就是说基本上把对象的引用与对象等同了。

<数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件  指出如何编写泛型算法。例如泛型方法能够找出一个数组的最大项。

然而,这种泛型方法有一个重要的局限:它只对Comparable接口的对象有效,因为它使用compareTo()方法作为所有比较决策的基础。

在许多情形下,这种处理方式是不可行的。例如:尽管假设Rectangle类实现Comparable接口有些过分,但即使实现了该接口,它所具有的compareTo方法恐怕还不是我们想要的方法。

例如,给定一个2x10的矩形和一个5x5的矩形,哪个是更大的矩形呢?答案恐怕依赖于我们是使用面积还是使用长度来决定。或者,如果我们试图通过一个开口构造该矩形,那么或许较大的矩形就是具有较大最小周长的矩形。

上述这些情形的解决方案是重写findMax,使它接受两个参数:一个是对象的数组,另一个是比较函数,该函数解释如何决定两个对象中哪个大哪个小。实际上,这些对象不再知道如何比较它们自己;这些信息从数组的对象中完全去除了。

一种将函数作为参数传递的独创方法是注意到对象即包含数据也包含方法,于是我们定义一个没有数据而只有方法的类,并传递类的一个实例。事实上,一个函数通过将其放在一个对象内部而被传递。这样的对象通常叫做函数对象。

示例一(显示函数对象想法的最简单实现):

package cn.functionObj.example;

import java.util.Comparator;

import cn.pre.example.FindMaxDemo;

public class CaseInsensitiveCompare implements Comparator<String> {

    @Override
public int compare(String lhs, String rhs) { return lhs.compareToIgnoreCase(rhs);
} public static<AnyType> AnyType findMax(AnyType[] arr,Comparator<? super AnyType> cmp) { int maxIndex = 0; for (int i = 0; i < arr.length; i++) if(cmp.compare(arr[i], arr[maxIndex]) > 0)
maxIndex = i; return arr [maxIndex]; } }
package cn.functionObj.example;

public class TestProgram {
public static void main(String[] args) {
String [] arr = {"ZEBRA","alligator","crocodile"};
System.out.println(CaseInsensitiveCompare.findMax(arr, new CaseInsensitiveCompare()));
}
}

运行结果输出:

对上述两个类代码解释:

findMax的第二个参数是Comparator类型的对象。接口Comparator在java.util指定并包含一个compare方法。

查看源码中的一小部分可以发现:

package java.util;

@FunctionalInterface
public interface Comparator<T> { int compare(T o1, T o2); }

实现接口Comparator<AnyType>类型的任何类都必须要有一个叫作compare的方法,该方法有两个泛型类型(AnyType)的参数并返回一个int型的量,遵守和compareTo相同的一般约定。因此,示例一中对compare的调用可以用来比较数组的项。另外带有限制的通配符用来表示查找数组中的最大项,那么该comparator必须知道如何比较这些项,或者这些项的超类型的那些对象。为了使用这种版本的findMax,findMax通过传递一个String数组以及实现一个comparator<String>的对象而被调用。这个对象属于CaseInsensitiveCompare类型,,它是我们编写的一个类。

代码示例已放置Github:https://github.com/youcong1996/The-Data-structures-and-algorithms/tree/master/Introduction

<数据结构与算法分析>读书笔记--函数对象的更多相关文章

  1. <数据结构与算法分析>读书笔记--运行时间计算

    有几种方法估计一个程序的运行时间.前面的表是凭经验得到的(可以参考:<数据结构与算法分析>读书笔记--要分析的问题) 如果认为两个程序花费大致相同的时间,要确定哪个程序更快的最好方法很可能 ...

  2. <数据结构与算法分析>读书笔记--利用Java5泛型实现泛型构件

    一.简单的泛型类和接口 当指定一个泛型类时,类的声明则包括一个或多个类型参数,这些参数被放入在类名后面的一对尖括号内. 示例一: package cn.generic.example; public ...

  3. <数据结构与算法分析>读书笔记--最大子序列和问题的求解

    现在我们将要叙述四个算法来求解早先提出的最大子序列和问题. 第一个算法,它只是穷举式地尝试所有的可能.for循环中的循环变量反映了Java中数组从0开始而不是从1开始这样一个事实.还有,本算法并不计算 ...

  4. <数据结构与算法分析>读书笔记--实现泛型构件pre-Java5

    面向对象的一个重要目标是对代码重用的支持.支持这个目标的一个重要的机制就是泛型机制:如果除去对象的基本类型外,实现的方法是相同的,那么我们就可以用泛型实现来描述这种基本的功能. 1.使用Object表 ...

  5. <数据结构与算法分析>读书笔记--数学知识复习

    数学知识复习是<数据结构与算法分析>的第一章引论的第二小节,之所以放在后面,是因为我对数学确实有些恐惧感.不过再怎么恐惧也是要面对的. 一.指数 基本公式: 二.对数 在计算机科学中除非有 ...

  6. <数据结构与算法分析>读书笔记--要分析的问题

    通常,要分析的最重要的资源就是运行时间.有几个因素影响着程序的运行时间.有些因素(如使用编译器和计算机)显然超出了任何理论模型的范畴,因此,虽然它们是重要的,但是我们在这里还是不能考虑它们.剩下的主要 ...

  7. <数据结构与算法分析>读书笔记--递归

    一.什么是递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的 ...

  8. <数据结构与算法分析>读书笔记--运行时间中的对数及其分析结果的准确性

    分析算法最混乱的方面大概集中在对数上面.我们已经看到,某些分治算法将以O(N log N)时间运行.此外,对数最常出现的规律可概括为下列一般法则: 如果一个算法用常数时间(O(1))将问题的大小削减为 ...

  9. <数据结构与算法分析>读书笔记--模型

    为了在正式的构架中分析算法,我们需要一个计算模型.我们的模型基本上是一台标准的计算机,在机器中指令被顺序地执行.该模型有一个标准的简单指令系统,如加法.乘法.比较和赋值等.但不同于实际计算机情况的是, ...

随机推荐

  1. 【Java并发编程】5、java中ConcurrentLinkedQueue类

    一.类结构: java.lang.Object java.util.AbstractCollection<E> java.util.AbstractQueue<E> java. ...

  2. Java - Thread 和 Runnable实现多线程

    Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式 概要 本章,我们学习“常用的实现多线程的2种方式”:Thread 和 Runnable.之所以说是常用的,是因为通过还可以通过jav ...

  3. JS 获取css transform中的值

    可以参考这位博主的文章https://www.cnblogs.com/zhenwoo/p/4993780.html 不想看直接想看怎么解决的看这: var translates= document.d ...

  4. apicloud 自定义模块的开发与上架注意事项

    模块开发要点与返回刷新页面注意事项 1.介绍 apicloud 除了使用官方提供的模块外,我们可以自定义一些模块供自己使用和上传到官方出售.针对没有提供或者价格过贵的模块,如果有时间自己可以进行研究. ...

  5. JavaScript高级编程———基本包装类型String和单体内置对象Math

    JavaScript高级编程———基本包装类型和单体内置对象 <script> var stringObject = new String("hello world") ...

  6. 【读书笔记】iOS-网络-使用Bonjour实现自组织网络

    Bonjour就是这样一种技术:设备可以通过它轻松探测并连接到相同网络中的其他设备,整个过程只需要很少的用户参与或是根本就不需要用户参与.该框架提供了众多适合于移动的使用场景,如基于网络的游戏,设备间 ...

  7. ArcGIS三种方式打断相交线------Planarize Lines工具

    1. 只有一个layer图层时,我们只需要选择”Planarize Lines“工具即可. (1)选择工具栏”Customize“选项: (2)选择Customize工具栏中的”Toolbars“选项 ...

  8. react native 第一次下载app的欢迎页+每次启动app的启动页设计

    欢迎各位同学加入: React-Native群:397885169 大前端群:544587175 大神超多,热情无私帮助解决各种问题. 我想我写的这篇博文可以帮助到很多人,接下来要分享的东西,对app ...

  9. 多媒体指令(AVX加速数组求和)

    #include <stdio.h> #include <intrin.h> #include <iostream> #include <ctime> ...

  10. VMWare虚拟机安装Linux系统时安装界面显示不全的解决、Linux分区

    1.只有最下面的按钮不全(可以显示字的一部分):可以用Tab键操控进行下一步 2.只有一半左右的界面:用Alt+鼠标左键移动安装界面 3.关于Linux分区:如果想用Linux进行深入操作,尽量不要选 ...