泛型概述

   泛型程序设计是程序设计语言的一种风格或范式。允许程序员在编写代码时使用一些以后才指定的类型,在实例化时(instantiate)作为参数指明这些类型。
   泛型的定义主要有以下两种:

  1. 在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)
  2. 在程序编码中一些包含参数的类。其参数可以代表类或对象等等。(现在人们大多把这称作模板)
    不论使用那个定义,泛型的参数在真正使用泛型时都必须作出指明。
    http://zh.wikipedia.org/wiki/%E6%B3%9B%E5%9E%8B

     对于C++来说,泛型很重的一个应用就是STL(标准模板程序库),STL可以让你重复使用既有的算法,而不必在类似情况下重新编写代码,这就是泛型算法的魅力,它不与特定的数据结构或对象类型绑定在一起,有很高的效率。
     让我看一个具体的例子,考虑下如何将普通C版本的线性查找变为泛型算法?
     如标准库中的strchr函数:
     char* strchr(char* s, char c);
     一个简易的实现代码如下:

char* strchr(char* s,  char c)
{
         while(*s!= ’\0’ && *s != c)
                   ++s;
         return *s == c ? s : (char *)0;
}

  考虑到一般化,可用一个指针last表示结束,则上述代码改为:

char* strchr(char* first, char* last, charc)
{
         while(first!= last && *s != c)
                   ++first;
         return first;
}

  对于char A[n],查找’a’; 可用char* result = strchr(A,A+n,’a’);

  在C++我们可以用template将参数类型参数化,实现一个更加一般的方法:
  这里用两种实现方式:

//Case1 :
  template<class T>
  T* find(T*first, T*last, const T& value);
//Case2:
   template<class Iterator, class T>
  Iteratorfind(Iterator first, Iterator last, const T& value)
  {
    while(first != last && *s != c)
       ++first;
     return first;
  }

  显然:方法2更具一般性,它不要求参数first和last类型必须为指针;
  那么对于这个更具一般性的方法,要求它具备那些能力呢?
  从上面代码中可以看出,需要:
  1) 比较能力,判断是否到达结尾(first != last)
  2) 提取能力(*s)
  3) 移动到下一个元素(++first)
  让我来看一个特殊的数据类型:链表;

   template<class T>
  struct node {
         T value;
         node* next;
  };

  那么我们如何通过上述泛型算法查找一个特定的节点呢,也就是如何实现上面的三种能力?
  首先考虑能否将Iterator 设置为 Node*,对于++操作,我们是希望移动到下一个元素,但是Node* 的++操作有既定的语法意义,无法进行操作符重载实现;
  我们可以写一个简单的外覆类,让它看上去像是Node*,但是可以对++进行重载;

    template<class T>
    struct node_wapper{
         Node* node;
         node_wapper(Node* n):node(n){};
         T &operator*(){return node->value;}
         node_wapper& operator++(){
           node = node->next;
           return *this;
        } //前置加
       bool operator!=(const node_wapper&i){
          rerurn node != i.node;
       }
};

 其函数调用可写为:
  find(node_wapper(head),node_wapper(),value);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Reducer类是Hadoop MapReduce框架中的一个关键组件。它定义了Reduce阶段的逻辑,负责将Map阶段输出的中间结果进行合并和处理。Reducer类的接口概述如下: ```java public interface Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> { void reduce(KEYIN key, Iterable<VALUEIN> values, Context context) throws IOException, InterruptedException; void setup(Context context) throws IOException, InterruptedException; void cleanup(Context context) throws IOException, InterruptedException; } ``` Reducer接口有四个参数: - KEYIN:输入键的类,通常与Mapper的输出键类相同。 - VALUEIN:输入值的类,通常与Mapper的输出值类相同。 - KEYOUT:输出键的类,通常是最终结果的键类。 - VALUEOUT:输出值的类,通常是最终结果的值类。 Reducer接口中定义了三个方法: - reduce()方法:Reduce阶段的主要逻辑实现。它接收输入键值对(key-value pair)的集合,并对相同键的值进行合并和处理,然后将结果输出到Context对象中。 - setup()方法:在Reducer实例初始化时调用,用于进行一些初始化操作,例如加载配置文件或建立数据库连接等。该方法在整个Reducer实例的生命周期内只会被调用一次。 - cleanup()方法:在Reducer实例销毁前调用,用于进行一些清理操作,例如关闭数据库连接或释放资源等。该方法在整个Reducer实例的生命周期内只会被调用一次。 Reducer类是一个抽象类,通常需要用户继承并实现其中的方法。在编写Reducer类时,需要特别注意输入键值对的集合是一个迭代器(Iterable),而不是一个列表。这是为了节省内存,因为在大规模数据处理时,可能会有大量的数据需要合并和处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One2zeror

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值