如何让List集合在新增或修改元素的同时集合依然保持有序

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

 

对于新增

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

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

 如何让List集合在新增或修改元素的同时集合依然保持有序

 

 

对于修改

修改集合某个元素的数值,则可能直接会导致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可以解决的事情,都可以牵引出来这么巧妙的运用,我想这就是编程的魅力所在。

 

如何让List集合在新增或修改元素的同时集合依然保持有序

上一篇:检测configMap,重载Pod内的业务容器


下一篇:设计模式-模板方法