java 集合比较器_Java集合-可比Vs比较器

java 集合比较器

Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects.

Java包含多个比较运算符(例如,<,<=,>,> =,==,!=),它们允许您比较原始值。 但是,这些运算符不能用于比较对象的内容。

Interface Comparable is used to allow objects of a class that implements the interface to be compared to one another. The interface contains one method, compareTo, that compares the object that calls the method to the object passed as an argument to the method.

接口可比较用于允许将实现接口的类的对象相互比较。 接口包含一个方法compareTo,该方法将调用该方法的对象与作为该方法的参数传递的对象进行比较。

For example, when using Collections.sort(List) with a List containing objects of a user-defined class A, then this class must implement the Comparable interface's method compareTo() to specify which property of the object will be used for comparisons/sorting.

例如,当将Collections.sort(List)与包含用户定义的类A的对象的List一起使用时,该类必须实现Comparable接口的方法compareTo(),以指定将对象的哪个属性用于比较/排序。

Otherwise, a ClassCastException will be thrown because Java tries to cast the objects to a Comparable.

否则,将抛出ClassCastException,因为Java尝试将对象强制转换为Comparable。

((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)

Note: The pre-defined classes like String, Integer, etc. already implement the interface Comparable, so any list containing objects of these classes do not throw a ClassCastException.

注意:诸如String,Integer等预定义的类已经实现了Comparable接口,因此包含这些类的对象的任何列表都不会抛出ClassCastException

For comparing objects of a user-defined class, which does not implement Comparable and which you cannot edit (e.g., because you do not have source code or its a class file in a jar library), we can use a custom class implementing the interface Comparator that similar to Comparable has one method, compare, that takes both the object being compared and the object being compared to as arguments.

为了比较未实现Comparable且无法编辑的用户定义类的对象(例如,因为您在jar库中没有源代码或其类文件),我们可以使用实现该接口的自定义类比较器 ,其类似于可比有一个方法,比较,一个同时被比较的对象和对象进行比较,以作为参数。

Java API reference:

Java API参考:

Interface Comparable has one method to be implemented by the class using it: 

public int compareTo(Object o)
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer if this object is less than, equal to, or greater than the specified object respectively.

Interface Comparator has a method compare with the following syntax: 

public int compare(Object o1,Object o2)
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer if the first argument is less than, equal to, or greater than the second respectively.

The following two examples will show how similar comparison functionality can be achieved by using either of the two interfaces: Comparable and Comparator.

以下两个示例将说明如何使用两个接口之一来实现相似的比较功能:Comparable和Comparator。

Example 1: Using Comparable 示例1:使用可比
// Time3.java (using Comparable)
public class Time3 implements Comparable< Time3 >
{
   private int hour;   // 0 - 23
   private int minute; // 0 - 59
   private int second; // 0 - 59

   // Time3 no-argument constructor: initializes each instance variable
   // to zero; ensures that Time3 objects start in a consistent state  
   public Time3()                                                      
   {                                                                   
      this( 0, 0, 0 ); // invoke Time3 constructor with three arguments
   } // end Time3 no-argument constructor                              

   // Time3 constructor: hour supplied, minute and second defaulted to 0
   public Time3( int h )                                                
   {                                                                    
      this( h, 0, 0 ); // invoke Time3 constructor with three arguments 
   } // end Time3 one-argument constructor                              

   // Time3 constructor: hour and minute supplied, second defaulted to 0
   public Time3( int h, int m )                                         
   {                                                                    
      this( h, m, 0 ); // invoke Time3 constructor with three arguments 
   } // end Time3 two-argument constructor                              

   // Time3 constructor: hour, minute and second supplied   
   public Time3( int h, int m, int s )                      
   {                                                        
      setTime( h, m, s ); // invoke setTime to validate time
   } // end Time3 three-argument constructor                

   // Time3 constructor: another Time3 object supplied           
   public Time3( Time3 time )                                    
   {                                                             
      // invoke Time3 three-argument constructor                 
      this( time.getHour(), time.getMinute(), time.getSecond() );
   } // end Time3 constructor with a Time3 object argument       

   // Set Methods
   // set a new time value using universal time; ensure that
   // the data remains consistent by setting invalid values to zero
   public void setTime( int h, int m, int s )
   {
      setHour( h );   // set the hour
      setMinute( m ); // set the minute
      setSecond( s ); // set the second
   } // end method setTime

   // validate and set hour
   public void setHour( int h )
   {
      hour = ( ( h >= 0 && h < 24 ) ? h : 0 );
   } // end method setHour

   // validate and set minute
   public void setMinute( int m )
   {
      minute = ( ( m >= 0 && m < 60 ) ? m : 0 );
   } // end method setMinute

   // validate and set second
   public void setSecond( int s )
   {
      second = ( ( s >= 0 && s < 60 ) ? s : 0 );
   } // end method setSecond

   // Get Methods
   // get hour value
   public int getHour()
   {
      return hour;
   } // end method getHour

   // get minute value
   public int getMinute()
   {
      return minute;
   } // end method getMinute

   // get second value
   public int getSecond()
   {
      return second;
   } // end method getSecond

   // convert to String in universal-time format (HH:MM:SS)
   public String toUniversalString()
   {
      return String.format(
         "%02d:%02d:%02d", getHour(), getMinute(), getSecond() );
   } // end method toUniversalString

   // convert to String in standard-time format (H:MM:SS AM or PM)
   public String toString()
   {
      return String.format( "%d:%02d:%02d %s",
         ( (getHour() == 0 || getHour() == 12) ? 12 : getHour() % 12 ),
         getMinute(), getSecond(), ( getHour() < 12 ? "AM" : "PM" ) );
   } // end method toString

   public int compareTo( Time3 time1 )
   {
      int hourCompare = this.getHour() - time1.getHour(); // compare hour

      // test the hour first
      if ( hourCompare != 0 )
         return hourCompare;

      int minuteCompare =
         this.getMinute() - time1.getMinute(); // compare minute

      // then test the minute
      if ( minuteCompare != 0 )
         return minuteCompare;

      int secondCompare =
         this.getSecond() - time1.getSecond(); // compare second

      return secondCompare; // return result of comparing seconds
   }
} // end class Time3
// Sort a list using the custom Comparator class TimeComparator.
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Sort4
{
   public void printElements()
   {
      List< Time3 > list = new ArrayList< Time3 >(); // create List

      list.add( new Time3(  6, 24, 34 ) );
      list.add( new Time3( 18, 14, 58 ) );
      list.add( new Time3(  6, 05, 34 ) );
      list.add( new Time3( 12, 14, 58 ) );
      list.add( new Time3(  6, 24, 22 ) );

      // output List elements
      System.out.printf( "Unsorted array elements:\n%s\n", list );

      // sort in order using a comparable            
      Collections.sort( list );

      // output List elements
      System.out.printf( "Sorted list elements:\n%s\n", list );
   } // end method printElements

   public static void main( String args[] )
   {
      Sort4 sort4 = new Sort4();
      sort4.printElements();
   } // end main
} // end class Sort4
Example 2: Using Comparator 示例2:使用比较器
public class Time2
{
   private int hour;   // 0 - 23
   private int minute; // 0 - 59
   private int second; // 0 - 59

   // Time2 no-argument constructor: initializes each instance variable
   // to zero; ensures that Time2 objects start in a consistent state  
   public Time2()                                                      
   {                                                                   
      this( 0, 0, 0 ); // invoke Time2 constructor with three arguments
   } // end Time2 no-argument constructor                              

   // Time2 constructor: hour supplied, minute and second defaulted to 0
   public Time2( int h )                                                
   {                                                                    
      this( h, 0, 0 ); // invoke Time2 constructor with three arguments 
   } // end Time2 one-argument constructor                              

   // Time2 constructor: hour and minute supplied, second defaulted to 0
   public Time2( int h, int m )                                         
   {                                                                    
      this( h, m, 0 ); // invoke Time2 constructor with three arguments 
   } // end Time2 two-argument constructor                              

   // Time2 constructor: hour, minute and second supplied   
   public Time2( int h, int m, int s )                      
   {                                                        
      setTime( h, m, s ); // invoke setTime to validate time
   } // end Time2 three-argument constructor                

   // Time2 constructor: another Time2 object supplied           
   public Time2( Time2 time )                                    
   {                                                             
      // invoke Time2 three-argument constructor                 
      this( time.getHour(), time.getMinute(), time.getSecond() );
   } // end Time2 constructor with a Time2 object argument       

   // Set Methods
   // set a new time value using universal time; ensure that
   // the data remains consistent by setting invalid values to zero
   public void setTime( int h, int m, int s )
   {
      setHour( h );   // set the hour
      setMinute( m ); // set the minute
      setSecond( s ); // set the second
   } // end method setTime

   // validate and set hour
   public void setHour( int h )
   {
      hour = ( ( h >= 0 && h < 24 ) ? h : 0 );
   } // end method setHour

   // validate and set minute
   public void setMinute( int m )
   {
      minute = ( ( m >= 0 && m < 60 ) ? m : 0 );
   } // end method setMinute

   // validate and set second
   public void setSecond( int s )
   {
      second = ( ( s >= 0 && s < 60 ) ? s : 0 );
   } // end method setSecond

   // Get Methods
   // get hour value
   public int getHour()
   {
      return hour;
   } // end method getHour

   // get minute value
   public int getMinute()
   {
      return minute;
   } // end method getMinute

   // get second value
   public int getSecond()
   {
      return second;
   } // end method getSecond

   // convert to String in universal-time format (HH:MM:SS)
   public String toUniversalString()
   {
      return String.format(
         "%02d:%02d:%02d", getHour(), getMinute(), getSecond() );
   } // end method toUniversalString

   // convert to String in standard-time format (H:MM:SS AM or PM)
   public String toString()
   {
      return String.format( "%d:%02d:%02d %s",
         ( (getHour() == 0 || getHour() == 12) ? 12 : getHour() % 12 ),
         getMinute(), getSecond(), ( getHour() < 12 ? "AM" : "PM" ) );
   } // end method toString
} // end class Time2
// Custom Comparator class that compares two Time2 objects.
import java.util.Comparator;

public class TimeComparator implements Comparator< Time2 >
{
   public int compare( Time2 time1, Time2 time2 )
   {
      int hourCompare = time1.getHour() - time2.getHour(); // compare hour

      // test the hour first
      if ( hourCompare != 0 )
         return hourCompare;

      int minuteCompare =
         time1.getMinute() - time2.getMinute(); // compare minute

      // then test the minute
      if ( minuteCompare != 0 )
         return minuteCompare;

      int secondCompare =
         time1.getSecond() - time2.getSecond(); // compare second

      return secondCompare; // return result of comparing seconds
   } // end method compare
} // end class TimeComparator
// Sort a list using the custom Comparator class TimeComparator.
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Sort3
{
   public void printElements()
   {
      List< Time2 > list = new ArrayList< Time2 >(); // create List

      list.add( new Time2(  6, 24, 34 ) );
      list.add( new Time2( 18, 14, 58 ) );
      list.add( new Time2(  6, 05, 34 ) );
      list.add( new Time2( 12, 14, 58 ) );
      list.add( new Time2(  6, 24, 22 ) );

      // output List elements
      System.out.printf( "Unsorted array elements:\n%s\n", list );

      // sort in order using a comparator            
      Collections.sort( list, new TimeComparator() );

      // output List elements
      System.out.printf( "Sorted list elements:\n%s\n", list );
   } // end method printElements

   public static void main( String args[] )
   {
      Sort3 sort3 = new Sort3();
      sort3.printElements();
   } // end main
} // end class Sort3

The above two examples produces the same output.

上面两个示例产生相同的输出。

Output: 输出:
Unsorted array elements:
[6:24:34 AM, 6:14:58 PM, 6:05:34 AM, 12:14:58 PM, 6:24:22 AM]
Sorted list elements:
[6:05:34 AM, 6:24:22 AM, 6:24:34 AM, 12:14:58 PM, 6:14:58 PM]

Conclusion:

结论:

Both Comparable and Comparator can be used to achieve sorting of a list of objects based on a particular property or field of that Object.

ComparableComparator都可以用于根据对象的特定属性或字段对对象列表进行排序。

Many times you have to create objects of a pre-defined class which does not implement Comparable and which may be part of a standard API or otherwise unavailable / undesirable for source editing. In such cases you can sort the list containing such objects by using the interface Comparator.

很多时候,您必须创建一个未定义Comparable的预定义类的对象,这些对象可能是标准API的一部分,或者对于源代码编辑而言是不可用/不受欢迎的。 在这种情况下,您可以使用接口Comparator对包含此类对象的列表进行排序。

翻译自: https://www.experts-exchange.com/articles/2523/Java-Collections-Comparable-Vs-Comparator.html

java 集合比较器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值