Objective C # select an appropriate set as needed

Source: Internet
Author: User
If you want to ask "which set is the best ?" My answer is: "depends on your needs ." Different sets have different features and are optimized for different behaviors .. Net Framework supports many similar collections: Lists, arrays, queues, stacks, and so on. In addition, C # supports multi-dimensional arrays. Its performance is different from other one-dimensional arrays or staggered arrays .. NET framework also contains many specialized sets. You can review the previously created Program Sets used. Since all sets implement the icollection interface, you can quickly find them. All classes that implement this interface are listed in the icollection Interface Description document. More than 20 classes are available for us.

When creating a set, you should consider which operations are most often performed on the set, which helps to select the correct set that suits your needs. In addition, to make the program more flexible, you should rely on the interface programming implemented by the collection class, even if you find that the set used in the original idea is incorrect, you can still replace it with other sets.

There are three different types of collections in. NET Framework: arrays, arrays of classes, and collection containers based on the hash principle. Arrays are the simplest and generally the fastest, so let's start from here. Arrays are the most common collection types.

Generally, when a set is required, the system. array class, or more appropriately, an array class of the specified type should be your first choice. The most important reason for array selection is that the array type is secure. Except for the generic type in C #2.0 (see item 1 in this book), other collections store references of the system. Object type. When we declare an array, the compiler will create a special system. array derivation for the specified type. For example, the declaration in the following example creates an integer array:

Private int [] _ Numbers = new int [100];

The array stores integers instead of system. object. This means that when we add, retrieve, or remove the value types in the array, we can avoid the efficiency loss caused by the packing and unpacking operations (see the 17th items in this book ). In the above example, a one-dimensional array that can store 100 integers is created during initialization. The memory units occupied by the array are set to 0. The initial values of the value type array are both 0, and those of the referenced type array are all null. We can use indexes to access each item in the array.

Int J = _ numbers [9];

In addition, we can use foreach or enumerator to traverse arrays.

Foreach ( Int I In _ Numbers)
{
Console. writeline (I. tostring ());
}
// Or


Ienumerator it = _ Numbers. getenumerator ();
While (It. movenext ())
{
IntI=(Int) It. Current;
Console. writeline (I. tostring ());
}

 

 

If you need to store objects of a single sequence, you should select an array to store them. But in general, our data structure is a complex set. This makes it easy for us to immediately go back to the C language style and switch to the use of staggered Arrays-an array containing arrays. Sometimes this is what we need. Each element of the layer set in the staggered array is an array.

 

 

Public   Class Myclass
{
Private   Int [] [] _ Jarged;
Public Myclass ()
{
_ Jagged =   New   Int [ 5 ] [];
_ Jarged [ 0 ] =   New   Int [ 10 ];
_ Jarged [ 1 ] =   New   Int [ 12 ];
_ Jarged [ 2 ] =   New   Int [ 7 ];
_ Jarged [ 3 ] =   New   Int [ 23 ];
_ Jarged [ 4 ] =   New   Int [ 5 ];
}
}

 

Each one-dimensional array stored in the outer array can be of different sizes. You can use an interleaved array to create arrays of different sizes. The disadvantage of staggered arrays is that column direction traversal is inefficient. For example, to check the value of the third column of each row in the staggered array, You need to perform two searches on the array for each row. In an interleaved array, the elements in the 0th rows and 3rd columns are not correlated with those in the 1st columns. Only multi-dimensional arrays can efficiently traverse the column direction. Previously, C and C ++ programmers used a one-dimensional array to map two-dimensional (or multi-dimensional) arrays. For previous C and C ++ programmersCodeIs clear:

Double num = myarray [I * rowlength + J];

Others prefer to write like this:

Double num = myarray [I, j];

However, C and C ++ do not support multi-dimensional arrays, whereas C # does. You can use multi-dimensional arrays to create a real multi-dimensional structure, which is clearer for you and the compiler. You can use a tag similar to the one-dimensional array declaration to create a multi-dimensional array.

Private int [,] _ multi = new int [10, 10];

The preceding statement creates a two-dimensional array with 100 elements in 10 × 10 arrays. In multi-dimensional arrays, the length of each dimension is a constant value. With this feature, the compiler can generate efficient initialization code. The initialization of an staggered number requires multiple initialization declarations. In the simple example earlier, we can see that you need to declare the interleaved array in the example five times. The larger the staggered array and the more dimensions it requires, the larger the initialization code is. You must do this manually. However, for multi-dimensional arrays, you only need to specify the dimension when initializing the declaration. In addition, multi-dimensional arrays can efficiently initialize array elements. For an array of value types, the elements corresponding to each index in the valid range are initialized as a value container. The content of these values is 0. Each index of an array of the reference type corresponds to null. For an array, its storage unit is also null.

In general, the traversal in multi-dimensional arrays is much faster than that in the staggered array, especially in the column direction or diagonal line direction. The compiler can use pointers.AlgorithmTo process any dimension in the array. For the staggered array, You need to search for the correct value in each one-dimensional array.

Multi-dimensional arrays can act as any set and play a role in many cases. Suppose you want to create a game on the board. You need to arrange a table with 64 areas as the chessboard:

Private square [,] _ theboard = new square [8, 8];

This initialization method creates an array that stores these square types. Assume that square is a reference type. Since these square types have not yet been created, the elements stored in each array are null. To initialize these elements, we must consider every dimension in the array.

 

For ( Int I =   0 ; I < _ Theboard. getlength ( 0 ); I ++ )
{
For ( Int J =   0 ; J < _ Theboard. getlength ( 1 ); J ++ )
{
_ Theboard [I, j]= NewSquare ();
}
}

 

However, in multi-dimensional arrays, you have more flexible element traversal methods. We can use the index of an array to obtain valid elements:

Square sq = _ theboard [4, 4];

If you need to traverse the entire set, you can use the iterator

 

Foreach (square SQ in _ theboard)
{
Sq. paintsquare ();
}

In contrast, if we use an interleaved array:

Foreach (square [] row in _ theboard)
{
Foreach (square SQ in row)
{
Sq. paintsquare ();
}
}

Adding a new dimension to the staggered array represents the need to declare a new foreach to complete the traversal. In multi-dimensional arrays, A foreach statement can generate code to check whether each dimension is out of bounds and to obtain all elements in the array. The foreach declaration generates special code to traverse each dimension of the array. The code generated by the foreach loop is equivalent to the following code:

For (INT I = _ theboard. getlowerbound (0); I <_ theboard. getupperbound (0); I ++)
{
For (Int J = _ theboard. getlowerbound (1); j <_ theboard. getupperbound (1); j ++)
{
_ Theboard [I, j]. paintsquare ();
}
}

The Code seems inefficient because the getlowerbound and getupperbound methods are called inside the loop, but this is actually the most efficient structure. The JIT compiler can cache the boundary of the array and cancel the internal cross-border judgment on the array.

The array class has two main disadvantages, which make other set types in. NET Framework useful. The first disadvantage affects the array size adjustment: the array cannot be dynamically adjusted. To adjust the size of an array dimension, you must create an array and copy all existing elements from the original array to the new array. It takes a lot of time to adjust the size: a new array must be allocated space, and all the elements in the existing array must be copied to the new array. Although the cost of copying and moving on hosting Stacks is not as expensive as in the C or C ++ era, it will still take time. More importantly, such operations may result in the application of outdated data. Consider the following code snippet:

 

Private   String [] _ Cities =   New   String [ 100 ];

Public   Void Setdatasource ()
{
Mylistbox. datasource=_ Cities;
}

Public   Void Addcity ( String Cityname)
{
String [] Temp =   New   String [_ Cities. Length +   1 ];
_ Cities. copyto (temp, 0 );
Temp [_ cities. Length] = Cityname;
_ Cities = Temp;
}

 

Even after the addcity method is called, the data source used by the list box is still an old version copy of The _ cities array. The newly added city will never be displayed in the list box.

The arraylist class is a high-level abstraction built on arrays. The arraylist set combines the features of one-dimensional arrays and linked lists. You can insert data in the arraylist or resize it. Arraylist delegates most of its responsibilities to its internal array, which means that the arraylist class has very similar functions and features as the array class. When we can use arraylist to easily cope with unknown size sets, this is also the main advantage of arraylist over array. Arraylist can be increased or decreased at any time. Although we still need to pay the cost of copying and moving array elements, the code of these algorithms has been written and tested. Because the array of data stored in the arraylist object is encapsulated, there will be no old data problem: the customer program will point to the arraylist object rather than the internal array. The arraylist set is the version of the Vector class in the C ++ standard class library in. NET Framework.

The queue and stack classes provide special interfaces based on system. array. Through the specific interfaces of these classes, the first-in-first-out queue and the second-in-first-out Stack are implemented. We must always remember that these sets use their internal one-dimensional arrays to store data. When we change them, they will also suffer performance losses.

. Net does not contain a set of linked list structures. Because of the efficient garbage collection mechanism, the appearance of the table structure is also reduced. If you do need to implement linked list behavior, you have two options. If you frequently add or remove a project and use the list, you can use a dictionary-type simple storage key and assign null to the value. You can use the listdictionary class to implement a key/value single-chain table. Or you can use the hybriddictionary class. When the collection is small, the hybriddictionary class uses listdictionary to deal with it, and hashtable is used for large sets. These collections are located in the system. Collections. Specialized namespace together with many other collections. However, if you use the linked list structure for the purpose of implementing some user commands, you can use the arraylist set instead. Although arraylist uses Arrays for internal storage, it can also insert elements at any position.

 

 

The other two types of dictionary-based collections are sortedlist and hashtable. They all contain key/value pairs. Sortedlist sorts keys, but hashtable does not. Hashtable provides quick search for a given key, while sortedlist provides the ability to traverse elements in sequence by keys. Hashtable searches by using the hash value of the key object. If the hash key is efficient enough, the time consumed by each search operation is a constant, that is, the time complexity is 0 (1 ). Sortedlist uses the binary method for searching. the time complexity of this algorithm is 0 (ln n ).

Finally, we will introduce the bitarray class. As the name suggests, this class is used to store binary data. The bitarray class uses an integer array to store data. Each storage unit in an integer array stores 32 binary values. This can achieve the goal of compression, but it also reduces the performance. Each get or set operation on bitarray will result in an integer operation that stores the target data and 31 other binary data. Bitarray contains some methods to perform Boolean operations on its internal values, such as or, XOR, and not. These methods use bitarray as the parameter and can be used to quickly filter multiple binary numbers in bitarray. Bitarray is specially optimized for bit operations. It should be used to store binary tag sets that are often used as masks, instead of using ordinary Boolean arrays.

Except for the array class, no other set classes in C # Of. NET Framework 1.x are strongly typed. They store all object references. C # generics contain a new version of the topology that can be created in a more universal manner. Generic is the best way to create a type security set. You can also use the current system. the abstract base classes contained in the collection namespace construct your own type security interfaces on a non-type security set: collectionbase and readonlycollectionbase provide the base classes for storing key/value sets. The dictionarybase class uses the implementation method of hash tables. Its features are very similar to those of hash tables.

When your class contains a set, you want to expose it to your class users. You have two ways to achieve this: using the indexer or implementing the ienumerable interface. At the beginning of this section, I show you how to use the [] Mark to obtain the items in the array. You can also use foreach to traverse the items in the array.

You can create a multi-dimensional indexer for your class. This is similar to the overload operator [] in C ++. Like arrays in C #, you can create a multi-dimensional indexer:

Public int this [int X, int y]
{
Get
{
Return computevalue (x, y );
}
}

Adding an index usually means that your type contains a set. This also means that your type should support the ienumerable interface. The ienumerable interface provides a standard mechanism for traversing all elements in a set by iteration.

Public interface ienumerable
{
Ienumerator getenumerator ();
}

// The getenumerator method returns an object that implements the ienumerator interface. The ienumerator interface supports traversal of sets:

Public interface ienumerator
{
Object current {Get ;}
Bool movenext ();
Void reset ();
}

In addition to the ienumerable interface, if you want to simulate an array of your type, you should also consider the ilist and icollection interfaces. If you want to simulate a dictionary for your type, you should consider implementing the idictionary interface. Of course, you can implement these huge interfaces by yourself. If you want to explain the implementation method, I am afraid it will take a lot of time. In fact, there is a simpler solution: when we want to create a set of special purposes, we can generate our class from collectionbase or dictionarybase.

Let's review the content covered in this section. The best set depends on the operations it performs and the space and time requirements of the application. In most cases, the array class provides the most efficient collection container. The emergence of multi-dimensional arrays in C # means that we can easily simulate multi-dimensional structures without worrying about performance sacrifice. When your program requires more flexible addition and deletion of items, which of the following Collection types can you use. Finally, when you want to create a simulated set of classes, you should implement the indexer and ienumerable interfaces for them.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.