java泛型:C#泛型秘诀(5.1)

  4.8 反转Sorted List里内容

  问题

  您希望在和列表类型中可以反转sorted list里内容同时又维持SortedList和SortedList<T>类原来功能无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能思路方法而又不需要重填列表

  解决方案

  ReversibleSortedList<TKey, TValue>类提供了这些功能它基于SortedList<TKey, TValue>类所以拥有相同功能它提供了额外功能是很容易反转已排序列表

  在例子化ReversibleSortedList<TKey, TValue>的后键是整数类型值是串类型连串无序数字和它们文本表达被插入到列表中这些项目是这样显示:

ReversibleSortedList<, > rsl = ReversibleSortedList<, >;
rsl.Add(2, "2");
rsl.Add(5, "5");
rsl.Add(3, "3");
rsl.Add(1, "1");
foreach (KeyValuePair<, > kvp in rsl)
{
  Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}


  列表输出显示为按升序排序(默认):

  1  1  2  2  3  3  5  5现在排列顺序通过设置ReversibleSortedListSortDirection属性被反转为降序为了重新排序需要Sort思路方法结果如下:

// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Descending;
// 重排列表.
rsl.Sort;
foreach (KeyValuePair<, > kvp in rsl)
{
  Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}


  这输出为降序:

  5  5  3  3  2  21  1

  当把个新项添加进列表它将按当前排列顺序被添加进去,但在添加完所有项后马上进行反转就可以保持列表中元素顺序

rsl.Add(4, "4");
  foreach (KeyValuePair<, > kvp in rsl)
  {
    Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
  }
  // 转换排序方向.
  rsl.Comparer.SortDirection = ListSortDirection.Ascending;
  // 重排列表.
  rsl.Sort;
  foreach (KeyValuePair<, > kvp in rsl)
  {
    Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}


  可以看到新项即按降序也按升序排列:

  5  5  4  4  3  3  2  2  1  1  1  1  2  2  3  3  4  4  5  5

  ReversibleSortedList<TKey, TValue>包含个实现了IComparer<T>接口嵌套类SortDirectionComparer<T>这个类可以在“讨论”这节中ReversibleSortedList<TKey, TValue>代码中看到个实现了IComparer<T>接口类可以做为ReversibleSortedList<TKey, TValue>构造思路方法参数来改变默认排序IComparer<T>接口实现了Compare思路方法:

Program
  {
    public Compare(T lhs, T rhs)
    {
       compareResult =
        lhs..CompareTo(rhs.);
      // 如果为降序, 则反转
       (SortDirection ListSortDirection.Descending)
        compareResult *= -1;
       compareResult;
    }
}


  Compare思路方法使用了SortDirectionComparer<T>类SortDirection属性来决定项排序这个属性在ReversibleSortedList<TKey, TValue>内部类SortDirectionComparer<T>例子中被设置SortDirection属性是在构造思路方法中被设置代码如下:

public ReversibleSortedList
  {
    this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
    this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
    this._size = 0;
    this._sortDirectionComparer = SortDirectionComparer<TKey>;
    this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}


  这允许它在指定时间内反转排列顺序但并没有重排列表中已存在为了实现这个功能需要在Reversible-SortedList<TKey, TValue>类中添加个新Sort思路方法以重排列表代码如下:

public void Sort
{
  //检查是否跟现有排序方向相同.
   (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
  {
    // 如果区别则进行反转.
    Array.Reverse(this.keys, 0, this._size);
    Array.Reverse(this.values, 0, this._size);
    // 设置当前排序.
    this._currentSortDirection = this._sortDirectionComparer.SortDirection;
   }
}


  讨论

  例4-3是ReversibleSortedList<TKey, TValue>类所有代码:

  (译者注:这个类代码很恐怖接近1300行不过代码很规范标准感觉应该是商业代码非常值得借鉴将来有时间我会专门写文章分析它请关注:我博客:http://cgbluesky.blog.163.com/)

  例4-3 ReversibleSortedList类

[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
public ReversibleSortedList<TKey, TValue> :
    IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
    IEnumerable<KeyValuePair<TKey, TValue>>,
    IDictionary, ICollection, IEnumerable
{
  SortDirectionComparer类定义#region SortDirectionComparer类定义
  public SortDirectionComparer<T> : IComparer<T>
  {  //ListSortDirection 枚举有两个值:
    //Ascending按升序排列Descending按降序排列
    private .ComponentModel.ListSortDirection _sortDir;
    //构造思路方法
    public SortDirectionComparer
    {  //默认为升序
      _sortDir = ListSortDirection.Ascending;
    }
    //重载构造思路方法
    public SortDirectionComparer(ListSortDirection sortDir)
    {
      _sortDir = sortDir;
    }
    //排序方向属性
    public .ComponentModel.ListSortDirection SortDirection
    {
      get { _sortDir; }
       { _sortDir = value; }
    }
    //实现IComparer<T>接口思路方法
    public Compare(T lhs, T rhs)
    {
       compareResult =
        lhs..CompareTo(rhs.);
  
      // If order is DESC, reverse this comparison.
       (SortDirection ListSortDirection.Descending)
        compareResult *= -1;
       compareResult;
    }
  }
  #endregion // SortDirectionComparer


  构造思路方法#region 构造思路方法

  //类型构造器
   ReversibleSortedList
  {
    ReversibleSortedList<TKey, TValue>.emptyKeys = TKey[0];
    ReversibleSortedList<TKey, TValue>.emptyValues = TValue[0];
  }
  //无参构造思路方法
  public ReversibleSortedList
  {
    this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
    this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
    this._size = 0;
    this._sortDirectionComparer = SortDirectionComparer<TKey>;
    this._currentSortDirection = this._sortDirectionComparer.SortDirection;
  }
  //用于指定排序方向构造思路方法
  public ReversibleSortedList(SortDirectionComparer<TKey> comparer)
    : this
  {
     (comparer != null)
    {
      this._sortDirectionComparer = comparer;
      this._currentSortDirection = _sortDirectionComparer.SortDirection;
    }
  }
  //用于指定字典构造思路方法
  public ReversibleSortedList(IDictionary<TKey, TValue> dictionary)
    : this(dictionary, (SortDirectionComparer<TKey>)null)
  {
  }
  //用于指定列表容量构造思路方法
  public ReversibleSortedList( capacity)
  {
     (capacity < 0)
    {
      throw ArgumentOutOfRangeException(
        "capacity", "Non-negative number required");
    }
    this.keys = TKey[capacity];
    this.values = TValue[capacity];
    this._sortDirectionComparer = SortDirectionComparer<TKey>;
    this._currentSortDirection = _sortDirectionComparer.SortDirection;
  }
  //用于指定字典和排序方向构造思路方法
  public ReversibleSortedList(IDictionary<TKey, TValue> dictionary,
                SortDirectionComparer<TKey> comparer)
    : this((dictionary != null) ? dictionary.Count : 0, comparer)
  {
     (dictionary null)
    {
      throw ArgumentNullException("dictionary");
    }
    dictionary.Keys.CopyTo(this.keys, 0);
    dictionary.Values.CopyTo(this.values, 0);
    Array.Sort<TKey, TValue>(this.keys, this.values,
                    this._sortDirectionComparer);
    this._size = dictionary.Count;
  }
  //用于指定容量和排序方向构造思路方法
  public ReversibleSortedList( capacity, SortDirectionComparer<TKey> comparer)
    : this(comparer)
  {
    this.Capacity = capacity;
  }
  #endregion //CTORS


  公有思路方法#region 公有思路方法

//添加元素
  public void Add(TKey key, TValue value)
  {
     (key.Equals(null))
    {
      throw ArgumentNullException("key");
    }
     num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
                        this._sortDirectionComparer);
     (num1 >= 0)
    {
      throw ArgumentException("Attempting to add duplicate");
    }
    this.Insert(~num1, key, value);
  }
  //ICollection<KeyValuePair<TKey, TValue>>接口思路方法实现
  public void Clear
  {
    this.version;
    Array.Clear(this.keys, 0, this._size);
    Array.Clear(this.values, 0, this._size);
    this._size = 0;
  }
  //判断是否包含指定键
  public bool ContainsKey(TKey key)
  {
     (this.IndexOfKey(key) >= 0);
  }
  //判断是否包含指定值
  public bool ContainsValue(TValue value)
  {
     (this.IndexOfValue(value) >= 0);
  }
  
  public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator
  {
     ReversibleSortedList<TKey, TValue>.Enumerator<TKey, TValue>(
          this);
  }
  //查找指定键
  public IndexOfKey(TKey key)
  {
  
     (key.Equals(null))
    {
      throw ArgumentNullException("key");
    }
     num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
                        this._sortDirectionComparer);
     (num1 < 0)
    {
       -1;
    }
     num1;
  }
  //查找指定值
  public IndexOfValue(TValue value)
  {
     Array.IndexOf<TValue>(this.values, value, 0, this._size);
  }
  //IDictionary<TKey, TValue>接口思路方法实现
  public bool Remove(TKey key)
  {
     num1 = this.IndexOfKey(key);
     (num1 >= 0)
    {
      this.RemoveAt(num1);
    }
     (num1 >= 0);
  }
  //移除指定索引元素
  public void RemoveAt( index)
  {
     ((index < 0) || (index >= this._size))
    {
      throw ArgumentOutOfRangeException("index", "Index out of range");
    }
    this._size--;
     (index < this._size)
    {
      Array.Copy(this.keys, ()(index + 1), this.keys, index,
            ()(this._size - index));
      Array.Copy(this.values, ()(index + 1), this.values, index,
            ()(this._size - index));
    }
    this.keys[this._size] = default(TKey);
    this.values[this._size] = default(TValue);
    this.version;
  }
  //排序
  public void Sort
  {
    // 检查是否跟现有排序方向相同.
     (this._currentSortDirection !=
      this._sortDirectionComparer.SortDirection)
    {
      // 如果区别则进行反转.
      Array.Reverse(this.keys, 0, this._size);
      Array.Reverse(this.values, 0, this._size);
      // 设置当前排序.
      this._currentSortDirection = this._sortDirectionComparer.SortDirection;
    }
  }
  //剪除多余空间
  public void TrimExcess
  {
     num1 = ()(this.keys.Length * 0.9);
     (this._size < num1)
    {
      this.Capacity = this._size;
    }
  }
  //获取指定键
  public bool TryGetValue(TKey key, out TValue value)
  {
     num1 = this.IndexOfKey(key);
     (num1 >= 0)
    {
      value = this.values[num1];
       true;
    }
    value = default(TValue);
     false;
  }
  
  #endregion // Public Methods


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

延伸阅读

最新评论

发表评论