1. 程式人生 > 實用技巧 >JavaEE - 09常用類3

JavaEE - 09常用類3

JavaEE - 09常用類3

(4)Java比較器

Comparable介面使用:Stringimplements Comparable<String>

    @Test
    public void test1(){
        String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));  //[AA, CC, DD, GG, JJ, KK, MM]
    }

(4.1)自然排序:java.lang.Comparable

  • Comparable介面強行對實現它的每個類的物件進行整體排序。被稱為類的自然排序。
  • 實現Comparable的類必須實現compareTo(Object obj)方法,兩個物件通過此方法的返回值來比較大小。
    • 如果當前物件this大於形參物件obj,返回正整數;當前物件小於形參物件,返回負整數;等於則返回零。
  • 實現Comparable介面的物件列表和陣列可以通過Collections.sort或Arrays.sort進行自然排序。
    • 實現此介面的物件可以用作有序對映的鍵或有序集合中的元素,無需指定比較器。
  • 對於類C的每一個e1和e2來說,當且僅當e1.compareTo(e2)==0與e1.equals(e2)具有相同的boolean值時,類C的自然排序才叫做與equals一致。
    • 建議最好使自然排序與equals一致。
  • String、包裝類等實現了Comparable介面,重寫了compareTo()方法,進行了從小到大的排序

按照價格從低到高排序:return Double.compare(this.price, goods.price );

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; } //指明商品比較大小的方式: 按照價格從低到高排序,再按照產品名稱從高到低排序 @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; return -this.name.compareTo(goods.name); } } throw new RuntimeException("輸入的資料型別不一致"); } // 省略其他程式碼 }

    @Test
    public void test2(){
        Goods goods1 = new Goods("Apple",2.9);
        Goods goods2 = new Goods("Banana",3.5);
        Goods goods3 = new Goods("Purple",3.2);
        Goods goods4 = new Goods("Perple",2.9);
        
        Goods[] arr = new Goods[]{goods1,goods2,goods3,goods4};
        //[Goods{name='Apple', price=2.9}, Goods{name='Banana', price=3.5}, Goods{name='Purple', price=3.2}, Goods{name='Perple', price=2.9}]
        System.out.println(Arrays.toString(arr)); 
        Arrays.sort(arr);
        //[Goods{name='Perple', price=2.9}, Goods{name='Apple', price=2.9}, Goods{name='Purple', price=3.2}, Goods{name='Banana', price=3.5}]
        System.out.println(Arrays.toString(arr)); 
    }

(4.2)定製排序:java.util.Comparator

  • 當元素的型別沒有實現java.lang.Comparable介面而又不方便更改程式碼,或者實現了java.lang.Comparable介面的排序規則不合適當前的操作,
    • 那麼可以考慮使用Comparator的物件來排序,強行對多個物件進行整體排序的比較。
  • 重寫compare(Object o1,Object o2)方法,比較o1和o2的大小:返回正整數,o1大於o2;負整數,o1小於o2;零,o1等於o2。
  • 可以將Comparator傳遞給sort方法(Collections.sort或Arrays.sort),從而允許在排序順序上實現精確控制。
  • 還可以使用Comparator來控制某些資料結構(有序set或有序對映)的順序,或者為沒有自然順序的物件collection提供排序。

    @Test
    public void test3(){
        String[] arr = new String[]{"AA","BB","AB","GG","JJ","DD"};
        Arrays.sort(arr, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof String && o2 instanceof  String){
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    return -s1.compareTo(s2);
                }
                throw new RuntimeException("輸入的資料型別不一致");
            }
        });
        System.out.println(Arrays.toString(arr)); //[JJ, GG, DD, BB, AB, AA]
    }

   @Test
    public void test4(){
        Goods goods1 = new Goods("Apple",2.9);
        Goods goods2 = new Goods("Banana",3.5);
        Goods goods3 = new Goods("Purple",2.2);
        Goods goods4 = new Goods("Purple",2.9);

        Goods[] arr = new Goods[]{goods1,goods2,goods3,goods4};
        // 按照產品名稱從低到高排序,再按照價格從高到低排序
        Arrays.sort(arr,new Comparator(){
            @Override
            public int compare(Object o1, Object o2){
                if(o1 instanceof Goods && o2 instanceof Goods){
                    Goods g1 = (Goods) o1;
                    Goods g2 = (Goods) o2;
                    if(g1.getName().equals(g2.getName())){
                        return -Double.compare(g1.getPrice(),g2.getPrice());
                    }else{
                        return g1.getName().compareTo(g2.getName());
                    }
                }
                throw new RuntimeException("輸入的資料型別不一致");
            }
        });
        //[Goods{name='Apple', price=2.9}, Goods{name='Banana', price=3.5}, Goods{name='Purple', price=2.9}, Goods{name='Purple', price=2.2}]
        System.out.println(Arrays.toString(arr));
    }

(4.3)說明

  • Java中的物件,正常情況下,只能進行比較: ==或 !=。不能使用 >或 < 。
  • 如果需要對多個物件進行排序,需要比較物件大小。可以使用兩個介面中的任何一個: Comparable或 Comparator。
  • Comparable介面的方式一旦確定,類的物件在任何位置都可以比較大小。Comparator介面屬於臨時性比較。

(5)System類

  • System類代表系統,系統級的很多屬性和控制方法都放置在該類的內部。該類位於java.lang包。
  • 由於該類的構造器是private的,所以無法建立該類的物件,無法例項化。其內部的成員變數和成員方法都是static的。
  • 成員變數:三個:in標準輸入流(鍵盤輸入)、out標準輸出流(顯示器)、err標準錯誤輸出流(顯示器)
  • 成員方法
    • native long currentTimeMillis():返回當前計算機時間,與GMT時間1970-01-01 00:00:00所差的毫秒數。
    • void exit(int status):退出程式。0代表正常退出,非零代表異常退出。使用該方法在圖形介面程式設計中實現程式的退出功能等。
    • void gc():請求系統進行垃圾回收。是否立刻回收,取決於系統中垃圾回收演算法的實現及系統執行時的情況。
    • String getProperty(String key):獲取系統中屬性名為key的屬性對應的值。
      • java.version / java.home/os.name / os.version/ user.name/ user.home / user.dir

(6)Math類

java.lang.Math提供了一系列靜態方法用於科學計算。其方法的引數和返回值型別一般為double型。

  • abs: 絕對值
  • acos,asin,atan,cos,sin,tan: 三角函式
  • sqrt: 平方根
  • pow(double a, double b): a的b次冪
  • log: 自然對數
  • max(double a, double b):
  • min(double a, double b):
  • random(): 返回0.0到1.0的隨機數
  • long round(double a): double型資料a轉換為long型(四捨五入)
  • toDegress(double angrad): 弧度 ->角度
  • toRadians(double angras): 角度 ->弧度

(7)BigDecimal與BigInteger

(7.1)BigInteger類

  • Integer類作為int的包裝類,能儲存的最大整型值為2^31-1, Long類也是有限的,最大為2^63-1。再大就無能為力了。
  • java.math包的BigInteger可以表示不可變的任意精度的整數。BigInteger提供所有Java的基本整數操作符的對應物,並提供java.lang.Math的所有相關方法。
  • BigInteger還提供了以下運算:模算術、GCD計算、質數測試、素數生成、位操作以及其他操作。
  • 構造器: BigInteger(String val):根據字串構建BigInteger物件
    @Test
    public void test7(){
        BigInteger bi = new BigInteger("12131321111111111111111113211321321321312");
        System.out.println(bi); //12131321111111111111111113211321321321312
    }

(7.2)BigDecimal類

  • 一般的Float類和Double類可以用來做科學計算或工程計算,但在商業計算中,要求數字精度比較高,故用到java.math.BigDecimal類。
  • BigDecimal類支援不可變的、任意精度的有符號十進位制定點數。
  • 構造器: public BigDecimal(String val) / public BigDecimal(double val)
  • 常用方法:
    • public BigDecimal add(BigDecimal augend)
    • public BigDecimal subtract(BigDecimal subtrahend)
    • public BigDecimal multiply(BigDecimal multiplicand)
    • public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
    @Test
    public void test5(){
        BigDecimal decimal1 = new BigDecimal("22.22");
        BigDecimal decimal2 = new BigDecimal("11.12");
        System.out.println(decimal1.add(decimal2));       //33.34
        System.out.println(decimal1.subtract(decimal2));  //11.10
        System.out.println(decimal1.multiply(decimal2));  //247.0864
        System.out.println(decimal1.divide(decimal2,2,2)); //2.00
    }

    @Test
    public void test6(){
        Double double1 = new Double("22.22");
        Double double2 = new Double("11.12");
        System.out.println(double1 + double2); //33.339999999999996
        System.out.println(double1 - double2); //11.1
        System.out.println(double1 * double2); //247.08639999999997
        System.out.println(double1 / double2); //1.9982014388489209
    }

    @Test
    public void test7(){
        BigDecimal bd = new BigDecimal("12435.351");
        BigDecimal bd2 = new BigDecimal("11");
        System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));      //1130.486
        System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));  //1130.486454545454545

    }

divide報錯

System.out.println(bd.divide(bd2)); Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(BigDecimal.java:1693) at Test03.main(Test03.java:49)