zoukankan      html  css  js  c++  java
  • 如何让List集合在新增或修改元素的同时集合依然保持有序

    如果说不考虑自定义编码逻辑的前提下,促使我们在对集合新增或修改元素后让集合有序排列,最傻最简单的做法就是.Net类库自带的Sort方法。

    对于新增

    当然有些杠精会说,我在新增元素的同时指定元素的位置不就行了嘛,但是这个操作需要人为的判断,我们需要知道集合的顺序,需要拿新元素和现有数据进行比对,才能知道插入在那里。

    如下面代码,我知道集合的数据内容并且知道插入的元素指具体是多少,我才知道7要插在9的前面。如果在集合数据量大且不知道新增元素具体值的情况下,这样的逻辑就很难实现。

     

    对于修改

    修改集合某个元素的数值,则可能直接会导致List集合的顺序发生变化,所以排序操作是毋庸置疑的,而本文要实现的是,在修改方法的同时就实现了对集合的排序,也就无需使用List.Sort方法,这也避免了Sort带来程序另外的开销。

    实现代码

     1    public class SortedList<T>:List<T>
     2     {
     3         public new void Add(T item)
     4         {
     5             //查询新元素在现有集合中的位置
     6             int position = this.BinarySearch(item); 
     7 
     8             //如果小于0则表示,元素在集合中不存在
     9             if (position<0)
    10             {
    11                 position = ~position; //使用“按位求补运算符”确定新元素的插入位置
    12             }
    13             this.Insert(position,item);
    14         }
    15 
    16         public void ModifySorted(T item,int index)
    17         {
    18             this.RemoveAt(index);
    19 
    20             int position = this.BinarySearch(item);
    21             if (position<0)
    22             {
    23                 position = ~position;
    24             }
    25             this.Insert(position, item);
    26 
    27         }
    28 
    29 
    30     }

    调用场景

     1    //创建一个SortedList并随机选择的数值填充
     2             SortedList<int> sortedList = new SortedList<int>();
     3             sortedList.Add(200);
     4             sortedList.Add(20);
     5             sortedList.Add(2);
     6             sortedList.Add(7);
     7             sortedList.Add(10);
     8             sortedList.Add(0);
     9             sortedList.Add(100);
    10             sortedList.Add(-20);
    11             sortedList.Add(56);
    12             sortedList.Add(55);
    13             sortedList.Add(57);
    14             sortedList.Add(200);
    15             sortedList.Add(-2);
    16             sortedList.Add(-20);
    17             sortedList.Add(55);
    18             sortedList.Add(55);
    19 
    20 
    21             foreach (var i in sortedList)
    22             {
    23                 Console.WriteLine(i);
    24             }
    25 
    26             //修改指定索引的值
    27             sortedList.ModifySorted(0, 5);
    28             sortedList.ModifySorted(1, 10);
    29             sortedList.ModifySorted(2, 11);
    30             sortedList.ModifySorted(3, 7);
    31             sortedList.ModifySorted(4, 2);
    32             sortedList.ModifySorted(2, 4);
    33             sortedList.ModifySorted(15, 0);
    34             sortedList.ModifySorted(0, 15);
    35             sortedList.ModifySorted(223, 15);
    36 
    37             Console.WriteLine();
    38             foreach (var i in sortedList)
    39             {
    40                 Console.WriteLine(i);
    41             }

    实现分析

    通过本文的技巧实现了在对List集合新增获取修改的同时自动的实现了集合的有序排列。则无需再另行调用List.Sort方法来实现排序,这样会带来另外的性能消耗。

    算法的精髓就在于BinarySearch函数和“按位求补运算符~”的妙用。

    BinarySearch方法基于内部的算法逻辑会得出一个正数和负数。

    如果返回的是正数,则表示集合内存在相同的元素,则返回值就是相同元素的索引位置,然后使用List.Insert方法就会将新元素插入到相同元素的前一位(类似于分组插入的抽象逻辑)

    如果返回的是负数,基于BinarySearch逻辑并使用“按位求补运算符~”,就可以将新元素有序的插入到指定位置,其有序排列核心关键还是在于BinarySearch的算法逻辑,只不过配合“按位求补运算符~”的妙用,促使新元素始终有序插入。

    心得

    本来一个Sort可以解决的事情,都可以牵引出来这么巧妙的运用,我想这就是编程的魅力所在。

    知识改变命运
  • 相关阅读:
    ActiveMQ持久化消息
    JAXB XML到java object的转换
    Jackson JSON Processor
    Spring JDBC入门
    Quatz入门
    Jersey 入门与Javabean
    记安装ubuntu server和一些程序
    libevent 入门教程:Echo Server based on libevent(转)
    Linux Eclipse 运行Protobuf
    精神状态: Confused
  • 原文地址:https://www.cnblogs.com/green-jcx/p/14968557.html
Copyright © 2011-2022 走看看