• Tidak ada hasil yang ditemukan

7 COMPARISON AND SORTING

Dalam dokumen C# 1: Basic Syntax and Semantics (Halaman 107-115)

public class Name {

  private string firstname;

private string lastname;

  public Name(string firstname, string lastname) {

    this.firstname = firstname;

this.lastname = lastname;

}

public string Firstname {

    get { return firstname; } }

public string Lastname {

get { return lastname; } }

public override string ToString() {

    return firstname + “ “ + lastname;

} }

If you executes the following method

private static void Test02() {

Name n1 = new Name(“Olga”, “Jensen”);

Name n2 = new Name(“Olga”, “Jensen”);

Console.WriteLine(n1);

Console.WriteLine(n2);

Console.WriteLine(n1 == n2);

Console.WriteLine(n1.Equals(n2));

}

you get the result:

and this is hardly what you would expect since the two Name objects represents the same name. If you then add the following method to the class Name:

public bool Equals(object obj) {

if (obj == null) return false;

if (obj.GetType() == GetType()) {

Name name = (Name)obj;

     return firstname.Equals(name.firstname) && 

lastname.Equals(name.lastname);

}

return false;

}

and performs the method Test2() again you get the result

Now the method Equals() returns the expected result. That the method Equals() should be written as shown above, you should just accept in this place, but the following happens:

- if the parameter is null the two objects can not be Equals()

- if the two objects are instances of the same class, the parameter is converted to a Name, and the two objects are equal if they has the same first name and the same last name

- else the two objects can not be Equals()

When the comparison operator returns false it is because the operator compare object references, and n1 and n2 are two different objects. The meaning of Equals() is that you can override it so that it compares the values of objects instead of their references, and when you writes a class you often has to override Equals() en ensure that comparison of objects works correct. When, as shown in Test1(), it seems different for strings, it’s because the class String overrides the equals operator, but it’s a whole other story. Note also, when the comparison of firstname and lastname works, it is because the class String implements Equals() so that it compares the values.

Consider the following method:

private static void Test03() {

string[] names = { ”Svend”, ”Knud”, ”Valdemar”, ”Harald” };

foreach (string s in names) Console.Write(s + “, “);

Console.WriteLine();

Array.Sort(names);

foreach (string s in names) Console.Write(s + “, “);

Console.WriteLine();

}

If you executes the method, you get the following result:

This example shows that it is quite simple to sort the array, since the class Array has a Sort() method. Executing the following method:

private static void Test04() {

Name[] names = { new Name(“Svend”, “Grathe”), new Name(“Knud”, “D. 5.”),

new Name(“Valdemar”, “Den store”), new Name(“Harald”, “Blåtand”) };

foreach (Name n in names) Console.Write(n + “, “);

Console.WriteLine();

Array.Sort(names);

foreach (Name n in names) Console.Write(n + “, “);

Console.WriteLine();

}

however, it will fail, and the program stops with an exception. The reason is that objects not in general can be compared and be arranged in a sequence. It supports the class String, but for your own classes you must define the comparison, and it is also natural, for the system obviously can not know how custom objects should be arranged. If it should be possible to compare objects of the type Name, the class must implements an interface:

public class Name : IComparable<Name>

{

  private string firstname;

private string lastname;

  public Name(string firstname, string lastname) {

    this.firstname = firstname;

this.lastname = lastname;

}

public string Firstname {

    get { return firstname; } }

public string Lastname {

get { return lastname; } }

public override string ToString() {

    return firstname + “ “ + lastname;

}

public override bool Equals(object obj) {

if (obj == null) return false;

if (obj.GetType() == GetType()) {

Name name = (Name)obj;

       return firstname.Equals(name.firstname) && 

lastname.Equals(name.lastname);

}

return false;

}

public int CompareTo(Name name) {

if (lastname.Equals(name.lastname)) return firstname.CompareTo(name.firstname);

return lastname.CompareTo(name.lastname);

} }

The class must implement an interface called IComparable<Name>, which says that it is possible to compare objects of the type Name. The interface defines a single method called CompareTo(), which is implemented at the end of the class. The method has a parameter of the type of the objects to be compared, and the method is implemented to meet the following protocol:

1. if the current object is less than the parameter, the method must return a value less than 0 (that is -1)

2. if the current object is greater than the parameter, the method must return a value greater than 0 (that is 1)

3. if the current object is equal to the parameter, the method must return 0

The class String implements this interface, and thus the method Test03() works. In this case I would compare Name objects such that if the two objects have the same last name, it is the first name that determines the order, otherwise the last name.

After the class Name is changed to implements Comparable<Name> also the method Test04() works:

The above examples shows that it is simple to sort an array. The only requirement is that the objects to be sorted, implements the interface Comparable. Also objects in a List can be sorted, and the following method will sort 4 Name objects:

private static void Test05() {

List<Name> names = new List<Name>();

names.Add(new Name(“Svend”, “Grathe”));

names.Add(new Name(“Knud”, “D. 5.”));

names.Add(new Name(“Valdemar”, “Den store”));

names.Add(new Name(“Harald”, “Blåtand”));

foreach (Name n in names) Console.Write(n + “, “);

Console.WriteLine();

names.Sort();

foreach (Name n in names) Console.Write(n + “, “);

Console.WriteLine();

}

You should note that the only difference is that the sorting method Sort() this time is a method in the class List which sorts the current list. An another important difference for the two sort methods is that the method to sort an array is a static method in the class Array, while the method to sort a list is an instance method in the class List, but more on that in the book C# 3.

Exercise 14: A sorted cup

Make a copy of the project CupProgram. When you run the program, it shows the values of the five cubes in random order. You should now change the program, such that it shows the cubes sorted. You have to change two things:

1. The class Cube must implements the interface Comparable<Cube>.

2. In the class Cup the method toss() should sort the cubes after rolled the cubes.

Dalam dokumen C# 1: Basic Syntax and Semantics (Halaman 107-115)