java泛型:泛型--约束

  9.5 约束

  有时候您必须确保添加进泛型列表中元素拥有某些约束(例如它们从个给定基类继承或它们实现了指定接口)在下面例子中我们实现了个简单可排序单链表链表由多个Node组成每个Node必须保证添加进去元素实现了IComparer接口您可以这样声明:

  public Node<T> : IComparable<Node<T>> where T : IComparable<T>

  这句代码定义了个泛型Node它操作类型TNode中T实现了IComparable<T>接口这意味着两个NodeT可以进行对比Node类通过约束(where T : IComparable<T>)来操作那些实现了IComparable接口类型因此您可以使用任何类型来替代T只要那种类型实现了IComparable接口

  例9-12举例介绍说明了完整接口实现并进行分析如下

  例9-12 使用约束

using ;
using .Collections.Generic;
UsingConstras
{
  public Employee : IComparable<Employee>
  {
    private name;
    public Employee( name)
    {
      this.name = name;
    }
    public override
    {
       this.name;
    }
    //实现接口
    public CompareTo(Employee rhs)
    {
       this.name.CompareTo(rhs.name);
    }
    public bool Equals(Employee rhs)
    {
       this.name rhs.name;
    }
  }
  //节点必须实现Node<T>IComparable接口
  //通过where关键字约束Node只接收实现了IComparable接口
  public Node<T> : IComparable<Node<T>> where T : IComparable<T>
  {
    //成员变量
    private T data;
    private Node<T> next = null; //下个节点
    private Node<T> prev = null; //前个节点
    //构造思路方法
    public Node(T data)
    {
      this.data = data;
    }
    //属性
    public T Data
    {
      get { this.data; }
    }
    public Node<T> Next
    {
      get { this.next; }
    }
    public CompareTo(Node<T> rhs)
    {  //这样使用是约束
       data.CompareTo(rhs.data);
    }
    public bool Equals(Node<T> rhs)
    {
       this.data.Equals(rhs.data);
    }
    //思路方法
    public Node<T> Add(Node<T> Node)
    {  //下面“我”代表类当前例子
       (this.CompareTo(Node) > 0) //小于我则放在我前面
      {
        Node.next = this; //新节点节点指向我
        //如果我有前个节点则新节点个节点指向它
        //新节点做为它个节点
         (this.prev != null)
        {
          this.prev.next = Node;
          Node.prev = this.prev;
        }
        //设置我个节点为新节点
        this.prev = Node;
        //从下面LinkedList<T>代码可以得知添加都是从
        //头节点开始判断只有新节点为头节点时才返回它
         Node;
      }
       //大于等于我则放在我后面
      {
        //如果我有下则跟下个进行对比
        //这里使用了递归直到新节点找到比它大节点为止
         (this.next != null)
        {
          this.next.Add(Node);
        }
        //如果我没有下个节点则设置新节点为我
        //节点并把它个节点指向我
        
        {
          this.next = Node;
          Node.prev = this;
        }
         this;
      }
    }
    public override
    {
       output = data.;
       (next != null)
      {  //这里也使用了递归打印链表上所有元素
        output ", " + next.;
      }
       output;
    }
  }
  public LinkedList<T> where T : IComparable<T>
  {
    //成员变量
    private Node<T> headNode = null;
    //索引器
    public T this[ index]
    {
      get
      {  //由于是链表这里需要从头遍历
         ctr = 0;
        Node<T> node = headNode;
        while (node != null && ctr <= index)
        {
           (ctr index)
          {
             node.Data;
          }
          
          {
            node = node.Next;
          }
          ctr;
        }
        throw ArgumentOutOfRangeException;
      }
    }
    //默认构造思路方法
    public LinkedList
    {
    }
    //思路方法
    public void Add(T data)
    {
       (headNode null)
      {
        headNode = Node<T>(data);
      }
      
      {
        headNode = headNode.Add( Node<T>(data));
      }
    }
    public override
    {
       (this.headNode != null)
      {
         this.headNode.;
      }
      
      {
         .Empty;
      }
    }
  }
  //测试类
   Test
  {
     void Main
    {  //创建个例子来进行思路方法
      Test t = Test;
      t.Run;
    }
    public void Run
    {
      LinkedList<> myLinkedList = LinkedList<>;
      Random rand = Random;
      Console.Write("Adding: ");
      for ( i = 0; i < 10; i)
      {
         nextInt = rand.Next(10);
        Console.Write("{0} ", nextInt);
        myLinkedList.Add(nextInt);
      }
      LinkedList<Employee> employees = LinkedList<Employee>;
      employees.Add( Employee("John"));
      employees.Add( Employee("Paul"));
      employees.Add( Employee("George"));
      employees.Add( Employee("Ringo"));
      Console.WriteLine("nRetrieving collections");
      Console.WriteLine("Integers: " + myLinkedList);
      Console.WriteLine("Employees: " + employees);
    }
  }
}


  运行结果:

Adding:2 1 2 6 1 5 9 0 5
Retrieving collections…
Integers:0,1,1,1,2,2,5,5,6,9
Employees:George, John, Paul, Ringo


  本例开头声明了个可以放到链表中类:

  public Employee : IComparable<Employee>

  这个声明指出Employee对象是可以进行对比可以看到Employee类实现了CompareTo和Equals思路方法注意:这些思路方法是类型安全(从参数传递进去类是Employee类型)LinkedList本身声明为只操作实现了IComparable接口类型:

  public LinkedList<T> where T : IComparable<T>

  这样就可以保证对列表进行排序LinkedList操作Node类型对象Node也实现了IComparable接口并要求它本身所操作数据也实现了IComparable接口:

  public Node<T> : IComparable<Node<T>> where T : IComparable<T>

  这些约束使得Node实现CompareTo思路方法变得安全而简单Node知道它将和其它Node数据进行对比:

public CompareTo(Node<T> rhs)
{
  // 这样使用是约束
   data.CompareTo(rhs.data);
}


  注意我们不需要测试rhs从而得知它是否实现了IComparable接口;我们已经约束了Node只能操作实现了IComparable接口数据



Tags:  泛型编程与stl 泛型编程 .net泛型 java泛型

延伸阅读

最新评论

发表评论