天天看點

Java 比較器 和 包裝類Java比較器Java包裝類

Java比較器

背景:

在Java中經常會涉及到多個對象的排序問題,那麼就涉及到對象之間的比較

  • Java中的對象, 正常情況下, 隻能進行比較

    ==

    比較對象位址值,是否相同

    !=

    比較對象位址值,是否相同,取反~

    不能使用 > 或 < 的

  • 但是在開發場景中,我們需要對多個對象進行排序,言外之意,就需要比較對象的大小
    Java 比較器 和 包裝類Java比較器Java包裝類
  • 以 JD 商城舉例場景: 查詢商品可以對商品進行:

    價格 銷量 評論 購買數...排序

    實際上這裡面是查詢每一個商品都是一個個

    商品對象

    對象屬性:

    商品名 評論數 價格 銷量 店鋪 圖檔位址...

  • 根據使用者點選,從資料庫中查詢到一個

    商品對象/數組

    進行排序,傳回資料給前端進行排序展示~

    當然, 一個功能可以有很多種實作方式, 也有直接在資料庫中根據傳過來的類型, 動态sql 直接在資料庫中查詢傳回排好序的資料!

Java實作對象排序:

  • 這裡主要介紹,以Java方式實作的對象排序...
  • Java實作對象排序的方式有兩種:

    自然排序:Java.lang.Comparable

    定制排序:Java.util.Comparator

自然排序:Java.lang.Comparable

看牌啊爆

Java Comparable接口強行對實作它的每個類的對象進行整體排序

這種排序被稱為:自然排序

  • Java類, 實作

    implements

    Comparable接口,重寫

    compareTo(Object o); 的方法;

  • 兩個對象即通過

    compareTo(Object o)

    方法的傳回值來比較大小

    如果目前對象 this 大于形參對象 o ,則傳回正整數 1

    如果目前對象 this 小于形參對象 o ,則傳回負整數 -1

    如果目前對象 this 等于形參對象 o ,則傳回零 0

  • 實作

    Comparable

    接口的類的對象數組(和有序集合)可以通過 Arrays.sort(和 Collections.sort )進行自動排序
  • Comparable的典型實作

    *String、包裝類等實作了Comparable接口,重寫了compareTo(obj)方法 *

    預設都是從小到大排序

    String:按照字元串中字元的Unicode值進行比較

    Character:按照字元的Unicode值來進行比較

    數值類型對應的包裝類以及BigInteger、BigDecimal:按照它們對應的數值大小進行比較

    Boolean:true 對應的包裝類執行個體大于 false 對應的包裝類執行個體

    true.compareTo( false); —傳回—> 1

    Date、Time等:後面的日期時間比前面的日期時間大

    2021.compareTo( 2020 ); —傳回—> 1

String、包裝類實作 Comparable接口

Demo

ComparaTest.Java

package com.wsm.comparatest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class ComparaTest {
    //Java String、包裝類等實作了Comparable接口
    public static void main(String[] args) {
        //String 類實作了, Comparable 接口!并且實作Comparable 接口!可以直接使用: Arrays.sort  Collections.sort  進行排序!
        String[] arr = new String[]{"AA","cc","ac","dd","aa","FF","ff"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr)); //[AA, FF, aa, ac, cc, dd, ff]

        //Char 的包裝類, Character 實作Comparable 接口!按照字元的Unicode值來進行比較;
        char a = 'a';
        char b = 'b';
        System.out.println("a="+(int)a+"\n"+"b="+(int)b);
        Character aC = 'a';
        Character bC = 'b';
        System.out.println(aC.compareTo(bC));               // a<b = -1

        //Boolean 包裝類實作了, Comparable 接口!
        Boolean ok = true;
        Boolean no = false;
        System.out.println("Boolean類型: true > false:"+ok.compareTo(no));

        //int 等基本資料類型的包裝類實作了, Comparable 接口!
        Integer one = 1;
        Integer two = 2;
        System.out.println("基本資料類型包裝類比較,直接根據值進行比較:"+one.compareTo(two));

        //Data 日期類型實作, Comparable 接口!
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Date thisYear = null;
        Date lastYear = null;
        try {
            thisYear = sdf.parse("2021");
            lastYear = sdf.parse("2020");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("日期類型比較,最近的日期最大:"+thisYear.compareTo(lastYear));
    }
}
           
Java 比較器 和 包裝類Java比較器Java包裝類

自然排序Demo

Commodity.Java

定義一個商品類:

/**
 * 建立一個商品類;
 */
public class Commodity implements Comparable {
    //商品名
    private String name;
    //商品價格
    private int price;
    //商品銷量
    private int sales;
    //點贊數
    private int like;
    //...更多不舉例子了...

    /** 實作implements Comparable接口,重寫 compareTo(Object o)類 */
    /** 指明商品比較大小的方式:按照價格從低到高排序,再按照産品名稱從高到低排序 */
    @Override
    public int compareTo(Object o) {
        // instanceof: 判斷傳入參數類型是否是 商品類型,進入if 進行比較!
        if(o instanceof Commodity){
            // Object 類型強制轉換,父類向下轉換!
            Commodity o1 = (Commodity) o;

            if(this.price > o1.price){              //如果目前對象 大于> 傳入對象傳回 1;
                return 1;
            }else if(this.price < o1.price){        //如果目前對象 小于< 傳入對象傳回 -1;
                return -1;
            }else {                                 //相等則在進行判斷...移此類推傳回 0;
                //return 0;                         //相等,應該傳回0 但我們還需要進行判斷商品名稱從高到底~
                //因為商品名稱是 String類型, String 本身已經實作了 comparable 是以👇👇
                return -this.name.compareTo(o1.name);//預設都是從小到大排序,加個 - 号取反~
            }
        }
        throw new RuntimeException("傳入的資料類型不一緻!");
    }

    //有參構造
    public Commodity(String name, int price, int sales, int like) {
        this.name = name;
        this.price = price;
        this.sales = sales;
        this.like = like;
    }

    //重寫toString 不然列印位址值!
    @Override
    public String toString() {
        return "Commodity{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", sales=" + sales +
                ", like=" + like +
                '}';
    }

       //省略 get/set..
}
           

上面的 compareTo(Object o) 方法中,如果隻是根據對象的一個屬性進行排序...

可以直接使用一個基本資料類型包裝類,進行 campareTo()

CommodityTest.Java

import java.util.Arrays;
/** 測試類 */
public class CommodityTest {
    public static void main(String[] args) {
        Commodity[] commodities = new Commodity[5];
        commodities[0] = new Commodity("a",1,1,1);
        commodities[1] = new Commodity("b", 1,1,1 );
        commodities[2] = new Commodity("c", 2,1,1 );
        commodities[3] = new Commodity("d", 3,1,1 );
        commodities[4] = new Commodity("a", 4,1,1 );
        System.out.println("第一次周遊數組:");
        for (Commodity commodity : commodities) {
            System.out.println(commodity);
        }
        //調用方法,給數組排序...
        Arrays.sort(commodities);
        System.out.println("Arrays.sort排序後周遊數組:");
        //name 從大到小~
        System.out.println("a="+(int)'a');
        System.out.println("b="+(int)'b');
        for (Commodity commodity : commodities) {
            System.out.println(commodity);
        }
    }
}
           
Java 比較器 和 包裝類Java比較器Java包裝類

定制排序:Java.Util.Comparator

看牌啊特

當元素沒有實作 Comparable接口, 而不友善修改代碼

或者實作了 Comparable 接口, 但其排序的操作,并不符合目前操作

  • String 預設從大小排,而我想要從小到大排序……

    而可以考慮 Comparator 類型對象來排序

Compartor

  • Comparator

    接口中隻有兩個抽象方法

    int compare(Object o1, Object o2);

    boolean equals(Object obj);

    接口實作類預設繼承了

    Object

    類的

    equals

    方法, 間接實作了方法。

    是以隻需實作

    int compare(Object o1, Object o2);

  • Arrays.sort 和 Collections.sort 存在多态方法

    Arrays.sort(T[],Comparator<? super T>);

    Collections.sort(T[],Comparator<? super T>);

實作:

  • 可以将

    Comparator

    接口實作類傳遞給 sort(T[],Comparator<? super T>) 方法,進而允許在排序順序上實作精确控制。
  • Comparator

    當作内部類,直接傳遞給方法,内部類中重寫

    int compare(Object o1, Object o2)方法

    比較o1和o2的大小

定制排序Demo

ComparatorTest.Java

import java.util.Arrays;
import java.util.Comparator;

/** ComparatorTest測試Demo */
public class ComparatorTest {
    //直接拿String 類進行操作, String類本身實作了 comparable接口;
    public static void main(String[] args) {
        /** 混亂的String[] */
        String[] arr = new String[]{"CC","MM","KK","AA","DD","GG","JJ","EE"};
        //預設從小到大排序
        System.out.println("預設從小到大排序");
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

        System.out.println("按照字元串從大到小的順序排列");
        //按照字元串從大到小的順序排列, new Comparator(){ ... } 内部類操作;
         Arrays.sort(arr,new Comparator(){
             //重寫compare(Object o1, Object o2) 方法
             @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));
    }
}
           
Java 比較器 和 包裝類Java比較器Java包裝類

兩者的差別

  • 隻要實作Comparable 接口的對象直接就成為一個可以比較的對象,但是需要修改源代碼
  • 用Comparator 的好處是不需要修改源代碼

    而是在待比較對象的類的外部實作一個比較器

    當某個自定義的對象需要作比較的時候,把待比較對象和比較器一起傳遞過去就可以實作排序功能。

  • 像String類、包裝類等JDK内置類實作了Comparable接口預設是升序排序

    如果要降序排序或指定其他排序規則隻能使用Comparator接口。

擴充:

instanceof

  • instanceof 是 Java 的一個二進制操作符,類似于 ==,>,< 等操作符
  • instanceof 是 Java 的保留關鍵字

    它的作用是測試它左邊的對象是否是它右邊的類的執行個體,傳回 boolean 的資料類型

Java 遵循 -- 得正~

System.out.println("Java遵循‘負負得正’ 數學公式:"+(-(-1)));
           

Java包裝類

什麼是包裝類型

Java 設計當初就提供了 8種基本資料類型

  • int byte short long

    float double

    boolean

    char

及對應的

包裝類

  • Integer Byte Short Long

    Float Double

    Boolean

    Character

    位于Java.lang包下

基本資料類型 和 包裝類基本一緻, 首字母大寫

類名首字母大寫, 本就是規範😀

就是 int 和 char 有點不一樣...

基本使用都一緻,這裡就以 int 舉例:

包裝類應用場景

  • 集合類泛型隻能是包裝類

    List<int> list1 = new ArrayList<>();

    編譯報錯

    List<Integer> list2 = new ArrayList<>();

    正常

  • 包含了每種基本類型的相關屬性,如最大值,最小值,所占位數等常用方法()...
  • 作為基本資料類型, 有時候我們想要進行一些對象的操作,

    基本資料類型

    無法直接完成!

    在Java中,一切皆對象,但八大基本類型卻不是對象

基本資料類型-----包裝類-----String 的轉換

  • 包裝類通過 Integer.toString() 将整型轉換為字元串

    Object 的方法~

  • 包裝類通過 Integer.parseInt("123") 将字元串轉換為int類型
  • 包裝類通過valueOf()方法, 将

    字元/數值

    轉換換成包裝類對象.

    雖然和基本資料類型存在

    自動裝箱/拆箱~

自動

裝箱

拆箱

Java5.0 之後新增的兩個功能:

自動裝箱

自動拆箱

  • 自動裝箱:

    裝箱就是将: 基本資料類型 ——轉換—— 為對象類型

    Integer a = 100;

  • 自動拆箱:

    拆箱就是将:對象類型 ——轉換為—— 基本資料類型

    int b = a;

PackClass.Java

/** 包裝類Demo */
public class PackClass {
    public static void main(String[] args) {
        //Integer 是int 類型的包裝類, 内置了大量的方法操作
        System.out.println("int 的最大值:"+Integer.MAX_VALUE);
        System.out.println("int 的最小值:"+Integer.MIN_VALUE);
        //...

        //構造方法:
        //  new Integer(int);       new Integer(String);
        //  将int 和 String 轉換成Integer對象; (JDK8已過時  ~)


        //建立一個Integer
        //1.構造函數
        Integer c1 = new Integer("540");
        //2.自動裝箱
        Integer c2 = 540;
        //3.使用提供的 valueof( int/String );
        // 構造函數方式已經被淘汰了... 使用String 注意String必須滿足是數字元, 不可以是 abc...
        Integer c3 = Integer.valueOf("540");
        //因為 Integer 是對象了,每一個對象都會又一個對應棧位址, == 比較位址是以傳回false
        System.out.println(c1==c2);
        System.out.println(c1==c3);
        System.out.println(c2==c3);
        //即使這樣也不例外!
        Integer c22 = 540;
        System.out.println(c2==c22);
        //但 Integer 和 int 進行比較是直接比較值, 底層會進行 "自動拆箱"
        int c33 = 540;
        System.out.println(c3==c33);
        //Integer 和 int 可以進行,數值計算/比較~
        System.out.println(c3+c33);


        //自動裝箱 拆箱
        Integer w = 123;
        System.out.println("自動裝箱:"+w);

        int w1 = new Integer("123");
        System.out.println("自動拆箱:"+w1);
        System.out.println("自動裝箱拆箱就是: 基本資料類型 和 引用類型(包裝類), 之間的互相轉換~");


        //String 包裝類 基本資料類型  互相轉換
        /**  基本類型轉換為字元串(3) */
        int c = 10;
        //使用包裝類的 toString() 方法
        String str1 = Integer.toString(c);
        //使用String類的 valueOf() 方法
        String str2 = String.valueOf(c);
        //用一個空字元串加上基本類型,得到的就是基本類型資料對應的字元串
        String str3 = c + "";

        /**  字元串轉換為基本類型 */
        String str = "8";
        //調用包裝類的parseXxx()靜态方法
        int d = Integer.parseInt(str);
        //調用包裝類的valueOf()方法轉換為基本類型的包裝類,會自動拆箱
        int e = Integer.valueOf(str);

        /**  字元串轉換為包裝類 */
        //通過構造函數 字元參數
        //通過valueof("");
        Integer integer = Integer.valueOf("8");
        System.out.println(integer);
    }
}
           
Java 比較器 和 包裝類Java比較器Java包裝類

總結:

Java八大基本資料類型都有對應的包裝類,使基本資料類型也具有對象的操作...

  • 并且内部定義了一些方法,友善使用..
  • 結合: 自動裝箱/拆箱 基本資料類型,使用起來更加的心用手~

Integer與int的差別

int是java提供的8種原始資料類型之一

  • Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類
  • int的預設值為0
  • Integer的預設值為null

    *即Integer可以區分出未指派和值為0的差別 *

    int則無法表達出未指派的情況

    判斷一個人考試,

    0分

    缺考

    則隻能使用Integer
  • 在JSP開發中,Integer的預設為null

    是以用el表達式在文本框中顯示時,值為空白字元串

    int預設的預設值為0,是以用el表達式在文本框中顯示時,結果為0

    int不适合作為web層的表單資料的類型

  • Integer提供了多個與整數相關的操作方法

    将一個字元串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量

    本文由部落格一文多發平台 OpenWrite 釋出!