Solve the sorting problem of TreeSet class _java

Source: Internet
Author: User
Tags comparable set set sorts wrapper

TreeSet supports two sorts of sorting methods: natural sorting and custom sorting. TreeSet default to natural sorting.

1, Natural sorting

TreeSet invokes the CompareTo (Object obj) method of the collection element to compare the size relationships between elements, and then arranges the collection elements in ascending order, which is a natural sort. (The prerequisite for comparison: two objects of the same type).

Java provides a comparable interface that defines a CompareTo (object obj) method that returns an integer value that the class implementing the interface must implement, and the object of the class that implements the interface can be compared to size. When an object calls the method to compare to another object, such as Obj1.comparto (OBJ2), if the method returns 0, the two objects are equal, and if a positive integer is returned, the OBJ1 is greater than obj2; If the method returns a negative integer, Indicates that obj1 is less than obj2.

Java common classes implement the comparable interface and provide a standard for comparing sizes. Common classes for implementing comparable interfaces:

    • BigDecimal, Bigineger, and all numeric-type corresponding wrapper classes: Compare the size of their corresponding values.
    • Character: The Unicode value of the character is compared.
    • Boolean:true the wrapper class instance that corresponds to the wrapper class instance that is greater than false.
    • String: Compares the Unicode values of characters in a string.
    • Date, Time: Later, date is larger than the previous time, date.

If you attempt to add an object to TreeSet, the class of that object must implement the comparable interface.

The following programs will have an error:

Class Err 
{ 
} public 
class Testtreeseterror 
{public 
static void Main (string[] args) 
{ 
TreeSet ts = new TreeSet (); 
Adds the two Err object Ts.add to the TreeSet collection 
(new Err ()); 
Ts.add (New ERR ()); 
} 

Description

The above program tried to add 2 Err objects to the TreeSet collection, and when the first object was added, there was no treeset, so there was no problem; When you add the second Err object, TreeSet calls the object's CompareTo (object obj) method is compared to other elements in the collection-if the corresponding class does not implement the comparable interface, a ClassCastException exception is thrown. And when an attempt is made to remove the first element of an element from the TreeSet, a ClassCastException exception is still thrown.

When you compare an object with the CompareTo (object obj) method, you need to cast the object obj of the comparison to the same type, because only two instances of the same class can be compared to size. That is, an object of the same class should be added to the TreeSet, or a ClassCastException exception will be thrown. For example, when you add a string object to the TreeSet, this operation is completely normal. The program throws an exception when the second date object is added to TreeSet the CompareTo (object obj) method of the object is invoked to compare to other elements in the collection.

In practical programming, programmers can define their own classes to add multiple types of objects to the TreeSet, provided that the user-defined class implements the comparable interface and implements the CompareTo (Object obj) method without coercion when implementing the interface. However, when manipulating the collection data in TreeSet, different types of elements will still occur classcastexceptio exceptions. (read it carefully and you'll understand)

When an object is added to the TreeSet collection, TreeSet calls the object's CompareTo (Object obj) method to compare the size of the other objects in the container, and then determines its storage location according to the red-black tree algorithm. If two objects are equal through CompareTo (object obj), treeset that they are stored in the same location.

For a treeset set, it determines that two objects are not equal: two objects return false through the Equals method comparison, or the same object is not returned 0--even if two objects are compared through CompareTo (object obj). TreeSet also treats them as two objects.

As shown in the following procedure:

Z class, overriding the Equals method, always returning false, 
//Overriding the CompareTo (Object obj) method, always returning a positive integer 
class Z implements comparable 
{ 
int age; 
Public Z (int age) 
{ 
this.age = age; 
} 
public boolean equals (Object obj) 
{return 
false; 
} 
public int compareTo (Object obj) 
{return 
1; 
} 
} 
public class Testtreeset 
{public 
static void Main (string[] args) 
{ 
TreeSet set = new TreeSet (); 
   z z1 = new Z (6); 
Set.add (z1); 
System.out.println (Set.add (z1)); 
The following output set set, will see 2 element 
System.out.println (set); 
Modifies the Age property 
((Z) (Set.first ()) of the first element of the set collection. Age = 9; 
The age attribute of the last element of the set collection is output, which is also changed to 9 
System.out.println ((((Z) (Set.last ())). age); 
 

Program Run Result:

True
[Treeset.z@1fb8ee3, treeset.z@1fb8ee3 ]
9
Description:

The same object was added two times in the program because the Equals () method of the Z1 object always returns False, and the CompareTo (object obj) method always returns 1. This treeset that the Z1 object is not the same as itself, so add two Z1 objects to the TreeSet. The two elements saved by the TreeSet object are actually the same element. So when you modify the age attribute of the first element in the TreeSet collection, the Age property of the last element in the TreeSet collection changes as well.

Summary : When an object needs to be put into the TreeSet, the Equals () method of the corresponding class of the object should be overridden to ensure that the method has the same result as the CompareTo (object obj) method. The rule is: if two objects return true through the Equals method comparison, the two objects should return 0 through the CompareTo (object obj) method.

If two objects return true through the Equals method comparison, but the two objects do not return 0 o'clock through the CompareTo (object obj) method, this causes TreeSet to save the two objects in a different location so that two objects can be added successfully. This is somewhat different from the rules for set sets.

If two objects return 0 o'clock through the CompareTo (object obj) method, they are more troublesome to return false by comparing the Equals method: Because two objects are equal through the CompareTo (object obj) method, TreeSet will try to keep them in the same location, but not in fact (otherwise there will be only one object), so it is more cumbersome to deal with.

If a mutable object is added to the TreeSet, and the subsequent program modifies the properties of the Mutable object, causing it to change in the order of size of the other objects, the TreeSet does not adjust their order again, and may even cause the two objects to be saved in TreeSet. They return 0 by comparing the Equals method returns the True,compareto (Object obj) method.

As shown in the following procedure:

 class R {int count; 
public R (int count) {This.count = count; 
Public String toString () {return "R" (Count property: "+ count +"); 
public boolean equals (Object obj) {if (obj instanceof R) {R r = (r) obj; 
if (R.count = = This.count) {return true; 
return false; 
public int hashcode () {return this.count; 
} public class TestHashSet2 {public static void main (string[] args) {hashset hs = new HashSet (); 
Hs.add (New R (5)); 
Hs.add (New R (-3)); 
Hs.add (New R (9)); 
Hs.add (New R (-2)); 
Print TreeSet collection, the SET elements are ordered SYSTEM.OUT.PRINTLN (HS); 
Remove the first element iterator it = Hs.iterator (); 
R-i = (r) it.next (); 
Assigns the Count property of the first element first.count =-3; 
outputting count again will see that the elements in the TreeSet are in a disordered state System.out.println (HS); 
Hs.remove (New R (-3)); 
SYSTEM.OUT.PRINTLN (HS); Output false System.out.println ("Does the HS contain R objects with Count-3?") 
"+ Hs.contains (New R (-3))); Output false System.out.println ("Does the HS contain a R object with Count 5?") 
 
"+ Hs.contains (new R (5))); } 
} 
 

Program Run Result:

[R (Count property:-3), R (Count property:-2), R (Count property: 5), R (Count property: 9)]
[R (Count property:-), R (Count property:-2), R (Count property: 5), R (Count property:-2)]
[R (Count property:-), R (Count property:-2), R (Count property: 5), R (Count property:-2)]
[R (Count property: 2), R (Count property:-2)]
Description

The R object in the above program is a normal rewrite of the Equals method and the comparable method class, both of which are based on the Count property of the R object. You can see that the results of the first output of the program are sorted sequentially. When the Count property of the R object is changed, the output of the program changes and contains the duplicate elements. Once the properties of the variable element in the TreeSet collection are changed, when the view deletes the object, the TreeSet also deletes the failure (even some of the objects in the collection are not modified, but elements that are equal to the modified element cannot be deleted), so delete the count

is a 2 R object, no elements are deleted; The program can delete the R object with Count 5, which indicates that TreeSet can delete objects that are not modified and that are not duplicated by objects that are modified.

Summary: Dealing with these objects with HashSet will be very complex and error prone. In order to make the program more robust, it is recommended that only immutable objects be placed in the HashSet and TreeSet collections.

2, custom sorting

The natural sort of treeset is based on the size of the collection elements and treeset them in ascending order. If you need to implement custom sorting, such as descending, you can use the comparator interface. The interface contains an int compare (t O1, T O2) method, which is used to compare the size of O1 and O2.

If you need to implement a custom sort, you need to create a TreeSet collection object and provide a comparator object that is associated with the TreeSet collection, which is responsible for the sorting logic of the collection elements.

As shown in the following procedure:

Class M { 
int age; 
 
Public M (int age) { 
this.age = age; 
} 
 
Public String toString () {return 
"M object (age: + age +)"; 
} 
} 
 
public class TestTreeSet3 {public 
static void Main (string[] args) { 
TreeSet ts = new TreeSet (new Comparator () { public 
int Compare (object O1, Object O2) { 
 
m m1 = (m) O1; 
M m2 = (m) O2; 
 
if (M1.age > M2.age) { 
return-1 
} else if (m1.age = = m2.age) {return 
0; 
} else {return 
1;< c21/>} 
} 
); 
Ts.add (New M (5)); 
Ts.add (New M ( -3)); 
Ts.add (New M (9)); 
SYSTEM.OUT.PRINTLN (TS); 
} 
 
 

Program Run Result:

[M Object (Age:9), M object (Age:5), M object (age:-3)]
Description:

The above program creates an anonymous internal class object for the comparator interface that is responsible for sorting the TS collection. So when we add M objects to the TS set, we do not need the M class to implement the comparable interface, because at this point TreeSet does not need to compare the size of the M object, but rather by the comparator object associated with TreeSet to sort the collection elements. When you use a custom sort, TreeSet sorts the collection elements regardless of the size of the collection element itself, but instead the comparator object is responsible for the collation of the collection elements.

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.