java中的compareto方法的詳細介紹


一.java中的compareto方法

1.返回參與比較的前后兩個字符串的asc碼的差值,如果兩個字符串首字母不同,則該方法返回首字母的asc碼的差值

     String a1 = "a";
        String a2 = "c";        
        System.out.println(a1.compareTo(a2));//結果為-2

 

2.即參與比較的兩個字符串如果首字符相同,則比較下一個字符,直到有不同的為止,返回該不同的字符的asc碼差值,

     String a1 = "aa";
        String a2 = "ad";        
        System.out.println(a1.compareTo(a2));//結果為-3

3.如果兩個字符串不一樣長,可以參與比較的字符又完全一樣,則返回兩個字符串的長度差值

     String a1 = "aa";
        String a2 = "aa12345678";        
        System.out.println(a1.compareTo(a2));//結果為-8

4.返回為正數表示a1>a2, 返回為負數表示a1<a2, 返回為0表示a1==a2;

5.數字類型不能用compareTo,nt跟int的比較不能用compareTo方法,直接用大於(>) 小於(<) 或者 等於(==) 不等於(!=)來比較即可

    int num1 = 4;
        int num2 = 5;        
        num1.compareTo(num2);//Cannot invoke compareTo(int) on the primitive type int 

你可以先把你的int型變量轉換成String再進行比較

復制代碼
     int num1 = 4;
        int num2 = 5;        
        
        //parse int to String    
        System.out.println((num1+"").compareTo(num2+""));//-1
        System.out.println(new Integer(num1).toString(). compareTo(new Integer(num2).toString()));//-1
        System.out.println(String.valueOf(num1).compareTo(String.valueOf(num2)));//-1
復制代碼

6.compareToIgnoreCase忽略大小寫

不考慮大小寫,按字典順序比較兩個字符串。此方法返回一個整數,它的正負號是調用 compareTo 的正負號,調用時使用了字符串的規范化版本,其大小寫差異已通過對每個字符調用 Character.toLowerCase(Character.toUpperCase(character)) 得以消除。
注意,此方法不 考慮語言環境,因此可能在某些特定的語言環境中產生不理想的排序。java.text 包提供 Collators 來完成語言環境敏感的排序。

7.int型可以直接比較,所以沒有用到compareTo比較,如果聲明的是Date、String、Integer、或者其他的,可以直接使用compareTo比較,

      Integer n1 = 5;
        Integer n2 = 6;
        System.out.println(n1.compareTo(n2));//-1        

 

二. Comparable<T>接口中的compareTo

 compareTo方法內必須做非空判斷(規范問題),當然int類型就不用了。

  注意事項:

    1、模型必須實現Comparable<T>接口

    2、Collection.sort(list)會自動調用compareTo,如果沒有這句,list是不會排序的,也不會調用compareTo方法

    3、如果是數組則用Arrays.sort(a)方法

注意要非空判斷,這里實例就不判斷了

復制代碼
  private int bookId;
    
    private String bookName;
    
    private int bookPrice;

    @Override
    public int compareTo(Book o) {
        // TODO Auto-generated method stub
        
    //return this.bookPrice-o.bookPrice;//按價格排序 升序
    //return o.bookPrice-this.bookPrice;//按價格排序 降序
        
    //return this.bookName.compareTo(o.bookName);//按書名排序 升序
        
    //先按 id 再按價格 最后按書名排序 升序
        int result = this.bookId - o.bookId;
        if(result == 0){
            result =this.bookPrice - o.bookPrice;
        }
        if(result == 0){
            result = this.bookName.compareTo(o.bookName);
        }        
        return result;
        
    }
復制代碼
復制代碼
package com.my.test.compare;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class TestCompare {
    public static void main(String[] args) {
        Book b1 = new Book(1, "語文", 20);
        Book b2 = new Book(2, "數學", 10);
        Book b3 = new Book(5, "英語", 10);
        Book b4 = new Book(4, "化學", 50);
        Book b5 = new Book(3, "化學", 10);
        //Book b6 = null;//不能為null,Collections.sort調用compareTo會報空指針異常
        
        List<Book> books = new ArrayList<>();         
        books.add(b1);
        books.add(b2);
        books.add(b3);
        books.add(b4);
        books.add(b5);
        System.out.println("Collections 排序前");
        
        for (Book book : books) {
            System.out.println(book);
            
        }
        Collections.sort(books);
        System.out.println("Collections 排序后");

        for (Book book : books) {
            System.out.println(book);
            
        }
        
        Book[] b = new Book[5];
        System.out.println(b.length);

        b[0] = b1;
        b[1] = b2;
        b[2] = b3;
        b[3] = b4;
        b[4] = b5;
        
        System.out.println("Arrays 排序前" );
        for (Book book : b) {
            System.out.println(book);
        }
        
        Arrays.sort(b);
        
        System.out.println("Arrays 排序后" );
        for (Book book : b) {
            System.out.println(book);
        }
        
        
    }

}
復制代碼

 在應用中我們為了好判斷狀態,一般處理為

復制代碼
    if(this.bookId<o.bookId){
            return -1;
        }else if(this.bookId>o.bookId){
            return 1;
        }else{
            return 0;
        }
復制代碼

 

返回值為 1,0.-1:

 

三。 Comparator接口

源碼:

復制代碼
@FunctionalInterface
public interface Comparator<T> {
  // 核心方法,用來比較兩個對象,如果o1小於o2,返回負數;等於o2,返回0;大於o2返回正數
  int compare(T o1, T o2);
  // 好像很少用到,一般都用對象自帶的equals
  boolean equals(Object obj);
  
  /**-----------下面的都是JDK1.8新增的接口,挑幾個放進去----------*/

  //返回反向排序比較器
  default Comparator<T> reversed() {
    return Collections.reverseOrder(this);
  }
  //根據名字知道,先進行compare比較后,再進行一次比較
  default Comparator<T> thenComparing(Comparator<? super T> other) {
    Objects.requireNonNull(other);
    return (Comparator<T> & Serializable) (c1, c2) -> {
      int res = compare(c1, c2);
      return (res != 0) ? res : other.compare(c1, c2);
    };
  }
  //對int類型的key進行比較
  public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
      (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
  }
  //返回正常順序的比較器
  public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
    return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
  }
}
復制代碼

一起來看一下如何使用,先來看一下JDK1.8以前的用法:

復制代碼
Collections.sort(books,new Comparator<Book>() {

            @Override
            public int compare(Book o1, Book o2) {
                // TODO Auto-generated method stub
                
                return o1.getBookPrice() - o2.getBookPrice();
                
            }
        });
復制代碼

或者創建一個比較器

復制代碼
package com.my.test.compare;

import java.util.Comparator;

public class SimpleCompator implements Comparator<Book> {

    @Override
    public int compare(Book o1, Book o2) {
        // TODO Auto-generated method stub
        return o1.getBookPrice() -o2.getBookPrice();
    }

}
復制代碼

 

Collections.sort(books,new SimpleCompator());

JDK1.8以前的用法要自己手動實現Comparator接口,然后調用Collections.sort(),傳入實現類來完成排序,非常麻煩,而JDK1.8則相對來說簡單了很多:

        Collections.sort(books,(Book a, Book b) -> { return a.getBookPrice()-b.getBookPrice(); });

或者可以簡單的寫為

        Collections.sort(books,(Book a, Book b) ->  a.getBookPrice()-b.getBookPrice());

甚至,我們可以不使用Collections.sort:

books.sort((Book a, Book b) -> a.getBookPrice()-b.getBookPrice() );

 詳見:http://www.manongjc.com/article/8005.html

 

compator 在 treeMap 中的 應用(基於key的排序):

treeMap默認的是基於key的從小到大 的排列

自定義排序也是基於key的,如果key object類型 可以自定義各種排序

            TreeMap<String, Person> treeMap = new TreeMap<>((String a,String b)-> b.compareTo(a));//降序
            TreeMap<String, Person> treeMap = new TreeMap<>((String a,String b)-> a.compareTo(b));//升序

TreeMap的按value排序(轉換成entry list 然后排序)漢字是按ascii碼排序的,不是漢語拼音

復制代碼
Person p1 = new Person(1, "A小紅");
        Person p2 = new Person(5, "D趙明");
        Person p3 = new Person(2, "W孫宇");
        Person p4 = new Person(9, "C黎明");
        
        TreeMap<String, Person> treeMap = new TreeMap<>();

        treeMap.put("45", p1);
        treeMap.put("12", p2);
        treeMap.put("85", p3);
        treeMap.put("33", p4);


        List<Map.Entry<String, Person>> entries = new ArrayList<>(treeMap.entrySet());

        Collections.sort(entries,
                (Map.Entry<String, Person> e1, Map.Entry<String, Person> e2) -> ((Person) e1.getValue()).getPersonName()
                        .compareTo(((Person) e2.getValue()).getPersonName()));
        System.out.println("按名字順序排列");
        for (Entry<String, Person> entry : entries) {
            System.out.println(entry.getValue());
            
        }
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM