Java中有一些比較運算符,如 >、<、==、!=、>=、<=、instanceof、equals
,不過其中大部分只能比較基本數據類型,引用數據類型除了==
、instanceof
、equals
以外,>
、<
這些都不能用。
因此,爲了知足對象排序的需求,java提供了兩個接口實現對象排序。java
Java實現對象排序的方式有兩種:git
java.lang.Comparable
java.util.Comparator
首先,看一下Comarable的典型例子,String類的比較。像String類或者包裝類中都實現了Comparable接口,重寫了compareTo()方法,在重寫的方法體中給出了比較兩個對象大小的方式。
如,String類中的compareTo方法中是按照字符串中字符的Unicode值進行從小到大的比較。算法
@Test public void testComparable(){ String[] arr = new String[]{"EE","FF","CC","BB","DD","AA"}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); // 打印:[AA, BB, CC, DD, EE, FF] }
對於天然排序來講,重寫compareTo(obj)
方法的規則以下:編程
對於自定義類,若是須要排序,那麼可讓自定義類實現Comparable接口,並重寫CompareTo方法在CompareTo中,指明如何對對象進行排序。數組
下面進行舉例:
假如,有一個商品類,有商品價格和商品名稱的屬性,如今須要根據商品的價格高低對多個對象進行排序。數據結構
public class Goods implements Comparable{ private String name; // 商品名稱 private double price; // 商品價格 public Goods() { } public Goods(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } // 重寫toString方法 @Override public String toString() { return "name:"+ name + ",price:"+ price; } // 指明如何進行排序,好比按照商品的價格從低到高進行排序 @Override public int compareTo(Object o) { if (o instanceof Goods){ Goods goods = (Goods)o; if(this.price > goods.price){ return 1; }else if(this.price < goods.price){ return -1; }else{ return 0; } } throw new RuntimeException("傳入的數據類型不一致!"); } }
測試,建立Goods對象數組,存儲四個商品,而後使用Arrays.sort進行排序,再進行輸出,代碼以下:dom
@Test public void testGoods(){ Goods[] arr = new Goods[4]; arr[0] = new Goods("Rapoo",189.9); arr[1] = new Goods("Logitech",239.5); arr[2] = new Goods("Razer",100.5); arr[3] = new Goods("Dell",79.9); System.out.println("排序前: " + Arrays.toString(arr)); Arrays.sort(arr); System.out.println("排序後: " + Arrays.toString(arr)); }
運行結果:ide
排序前: [name:Rapoo,price:189.9, name:Logitech,price:239.5, name:Razer,price:100.5, name:Dell,price:79.9] 排序後: [name:Dell,price:79.9, name:Razer,price:100.5, name:Rapoo,price:189.9, name:Logitech,price:239.5]
這樣,輸出的對象數組就會按照商品的價格從低到高進行排序。
總結一下:使用天然排序來比較自定義類的對象大小,先讓自定義實現Comparable接口,而後重寫compareTo()方法,在方法體內寫具體要根據什麼邏輯來比較對象的大小。函數
當元素的類型沒有實現java.lang.Comparable
接口而又不方便修改代碼,或者實現java.lang.Comparable
接口的排序規則不適合當前的操做,那麼能夠考慮使用Comparator
的對象來排序,強行對多個對象進行總體排序的比較。測試
一樣,實現類須要重寫接口的方法compare()
,compare方法的重寫規則以下:
對於方法compare(Object o1,Object o2)
,比較o1和o2的大小:
示例,仍是使用上面Goods.class代碼爲例:
@Test public void testGoods2(){ Goods[] arr = new Goods[4]; arr[0] = new Goods("Rapoo",189.9); arr[1] = new Goods("Logitech",239.5); arr[2] = new Goods("Razer",100.5); arr[3] = new Goods("Dell",79.9); Arrays.sort(arr, new Comparator() { // 指明商品比較大小的方式:按照商品名稱從低到高排序,若是是相同價格的就按照價格從高到低排序 @Override public int compare(Object o, Object t1) { if (o instanceof Goods && t1 instanceof Goods){ Goods g1 = (Goods)o; Goods g2 = (Goods)t1; if (g1.getName().equals(g2.getName())){ return -Double.compare(g1.getPrice(),g2.getPrice()); }else{ return g1.getName().compareTo(g2.getName()); } } throw new RuntimeException("輸入的數據類型不一致"); } }); System.out.println(Arrays.toString(arr)); }
除此以外,能夠將 Comparator 傳遞給 sort 方法(如 Collections.sort 或 Arrays.sort),從而容許在排序順序上實現精確控制。
示例:
@Test public void testComparator(){ String[] arr = new String[]{"EE","FF","CC","BB","DD","AA"}; Arrays.sort(arr,new Comparator(){ // 定製規則,讓字符串從大到小進行排序 @Override public int compare(Object o, Object t1) { if (o instanceof String && t1 instanceof String){ String s1 = (String)o; String s2 = (String)t1; return -s1.compareTo(s2); } throw new RuntimeException("輸入的數據類型不一致"); } }); System.out.println(Arrays.toString(arr)); }
還可使用 Comparator 來控制某些數據結構(若有序 set或有序映射)的
順序,或者爲那些沒有天然順序的對象 collection 提供排序。
System類表明系統,系統級的不少屬性和控制方法都放置在該類的內部。該類位於java.lang包。
因爲該類的構造器是private的,因此沒法建立該類的對象,也就是沒法實例化該類。其內部的成員變量和成員方法都是static的,因此也能夠很方便的進行調用。
成員變量
System類內部包含in、out和err
三個成員變量,分別表明標準輸入流(鍵盤輸入)
,標準輸出流(顯示器)
和標準錯誤輸出流(顯示器)。
成員方法native long currentTimeMillis(): :
該方法的做用是返回當前的計算機時間,時間的表達格式爲當前計算機時間和GMT時間(格林威治時間)1970年1月1號0時0分0秒所差的毫秒數。
void exit(int status)
該方法的做用是退出程序。其中status的值爲0表明正常退出,非零表明異常退出。 使用該方法能夠在圖形界面編程中實現程序的退出功能等。
void gc()
該方法的做用是請求系統進行垃圾回收。至於系統是否馬上回收,則取決於系統中垃圾回收算法的實現以及系統執行時的狀況。String getProperty(String key)
該方法的做用是得到系統中屬性名爲key的屬性對應的值。系統中常見的屬性名以及屬性的做用以下表所示:
屬性名 | 說明 |
---|---|
java.version | Java運行環境的版本 |
java.home | Java安裝目錄 |
os.name | 操做系統名稱 |
os.version | 操做系統版本 |
user.name | 用戶名稱 |
user.home | 用戶的主目錄 |
user.dir | 用戶當前工做目錄 |
示例:
@Test public void testSystem(){ String javaVersion = System.getProperty("java.version"); System.out.println("java的version:" + javaVersion); String javaHome = System.getProperty("java.home"); System.out.println("java的home:" + javaHome); String osName = System.getProperty("os.name"); System.out.println("os的name:" + osName); String osVersion = System.getProperty("os.version"); System.out.println("os的version:" + osVersion); String userName = System.getProperty("user.name"); System.out.println("user的name:" + userName); String userHome = System.getProperty("user.home"); System.out.println("user的home:" + userHome); String userDir = System.getProperty("user.dir"); System.out.println("user的dir:" + userDir); }
java.lang.Math
提供了一系列靜態方法用於科學計算。其方法的參數和返回值類型通常爲double類型。經常使用方法以下:
abs
:求絕對值acos,asin,atan,cos,sin,tan
:三角函數sqrt
:求平方根pow(double a,doble b)
:求a的b次冪log
:求天然對數exp
:e爲底指數max(double a,double b)
:求a,b的最大值min(double a,double b)
:求a,b的最小值random()
:返回0.0 到1.0 的隨機數long round(double a)
:double型數據a 轉換爲long 型(四捨五入)toDegrees(double angrad)
:弧度—> 角度toRadians(double angdeg)
:角度—> 弧度BigInteger類
Integer類做爲int的包裝類,能存儲的最大整型值爲2^31 -1
,Long類也是有限的,最大爲2^63 -1
。若是要表示再大的整數,不論是基本數據類型仍是他們的包裝類都無能爲力,更不用說進行運算了。
java.math包的BigInteger
能夠表示不可變的任意精度的整數
。BigInteger
提供全部Java的基本整數操做符的對應物,並提供java.lang.Math
的全部相關方法。另外,BigInteger 還提供如下運算:模算術、GCD 計算、質數測試、素數生成、位操做以及一些其餘操做。
BigDecimal類
通常的Float類和Double類能夠用來作科學計算或工程計算,但在 商業計算中,到 要求數字精度比較高,故用到java.math.BigDecimal類。
BigDecimal類支持不可變的、任意精度的有符號十進制定點數。構造器
經常使用方法