一.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());
}

