16--常用类和基础API--06

1、包装类

1.1 包装类概述

Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类,如下:

基本类型

对应的包装类(位于java.lang包中)

byte

Byte

short

Short

int

Integer

long

Long

float

Float

double

Double

char

Character

boolean

Boolean

1.2 装箱与拆箱

基本类型与对应的包装类对象之间,来回转换的过程称为【装箱】与【拆箱】:

什么是装箱:从基本类型转换为对应的包装类对象。

什么是拆箱:从包装类对象转换为对应的基本类型。

以Integer与int为例演示他们之间的转换:

基本类型 转 包装对象(自动装箱)

Integer i = new Integer(4);				// 使用构造函数函数
Integer iii = Integer.valueOf(4);		// 使用包装类中的valueOf方法

包装对象 转 基本类型(自动拆箱)

int num = i.intValue();

1.3 自动装箱与自动拆箱

由于我们经常要做基本类型与包装类之间的转换,从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:

Integer i = 4;		// 自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;		// 等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
// 加法运算完成后,再次装箱,把基本数值转成对象。

1.4 基本类型与字符串之间的转换

1.4.1 基本类型 ---> String

//基本类型 --> String

int i = 10;
//拼接方式
String s = i +"";

//静态toString(参数)方法
String s =  Integer.toString(10);

//静态方法valueOf(参数), valueOf()这个方法可以把任意的基本类型转成String类型
String s = String.valueOf(20);

1.4.2 String ---> 基本类型

将字符串的数据转换成int类型的数据

public class Demo18WrapperParse {
    public static void main(String[] args) {
        //字符串 --> int 
        String i = "100";
        int num = Integer.parseInt(i); 
        double v = Double.parseDouble("3.34");
        float v1 = Float.parseFloat("3.3");
        //...所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型
    }
}

除了Character类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型:

方法

说明

public static byte parseByte(String s)

将字符串参数转换为对应的byte基本类型。

public static short parseShort(String s)

将字符串参数转换为对应的short基本类型。

public static int parseInt(String s)

将字符串参数转换为对应的int基本类型。

public static long parseLong(String s)

将字符串参数转换为对应的long基本类型。

public static float parseFloat(String s)

将字符串参数转换为对应的float基本类型。

public static double parseDouble(String s)

将字符串参数转换为对应的double基本类型。

public static boolean parseBoolean(String s)

将字符串参数转换为对应的boolean基本类型。

如果字符串参数的内容无法正确转换为对应的基本类型,则会抛java.lang.NumberFormatException异常。

1.4.3 Integer 和 int 有什么区别?

Integer 和 int 有什么区别?

        int是基本数据类型, Integer是int的包装类

        int默认值为0 , Integer的默认值null

或者什么情况下使用Integer, int?

        举例:小明考试,最终得到0分,请问他是去考试还是没去考试?去考试 用int

        小明考试,最终null,请问他是去考试还是没去考试?没有考试 用Integer

2、BigInteger类

2.1 BigInteger类概述

java中long型为最大整数类型,对于超过long型的数据如何去表示呢?在Java的世界中,超过long型的整数已经不能被称为整数了,它们被封装成BigInteger对象.在BigInteger类中,实现四则运算都是方法来实现,并不是采用运算符.

2.2 BigInteger类的构造方法

方法

说明

public BigInteger(String val)

将字符串的数组封装成BigInteger对象

2.3 BigInteger类的常用方法

方法

说明

public BigInteger add(BigInteger val)

两个BigInteger进行相加,并返回BigInteger

public BigInteger subtract(BigInteger val)

两个BigInteger进行相减,并返回BigInteger

public BigInteger multiply(BigInteger val)

两个BigInteger进行相乘,并返回BigInteger

public BigInteger divide(BigInteger val)

两个BigInteger进行相除,并返回BigInteger,整数相除只保留整数部分。

public BigInteger remainder(BigInteger val)

两个BigInteger进行取余数

package com.suyv.math;

import org.junit.Test;

import java.math.BigInteger;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:43
*@Description: TODO
*/
public class BigIntegerDemo01 {
    BigInteger big1 = new BigInteger("12345678912345678912345678");
    BigInteger big2 = new BigInteger("78923456789123456789123456789");

    @Test
    public void Test01(){
        // 加
        System.out.println(big1.add(big2));
        // 减
        System.out.println(big2.subtract(big1));
        // 乘
        System.out.println(big2.multiply(big1));
        // 除
        System.out.println(big2.divide(big1));
        // 取余
        System.out.println(big2.remainder(big1));
    }

}

3、BigDecimal类

3.1 BigDecimal类的引入

在程序中执行下列代码,会出现什么问题?

System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);

double和float类型在运算中很容易丢失精度,造成数据的不准确性,Java提供我们BigDecimal类可以实现浮点数据的高精度运算

3.2 BigDecimal类的构造方法

方法名

说明

public BigDecimal(String val)

将String类型的数组封装为BigDecimal对象

建议浮点数据以字符串形式给出,因为参数结果是可以预知的

3.3 BigDecimal类的常用方法

方法名

说明

public BigDecimal add(BigDecimal augend)

浮点类型数据相加操作

public BigDecimal subtract(BigDecimal subtrahend)

浮点类型数据相减操作

public BigDecimal multiply(BigDecimal multiplicand)

浮点类型数据相乘操作

public BigDecimal divide(BigDecimal divisor)

浮点类型数据相除操作

public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)

浮点类型数据相除操作,按照指定的模式,保留几位小数

package com.suyv.math;

import org.junit.Test;

import java.math.BigDecimal;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:50
*@Description: TODO
*/
public class BigDecimalDemo01 {

    BigDecimal big1 = new BigDecimal("0.09");
    BigDecimal big2 = new BigDecimal("0.01");

    @Test
    public void Test01(){
        // 加
        System.out.println(big1.add(big2));
        // 减
        System.out.println(big1.subtract(big2));
        // 乘
        System.out.println(big2.multiply(big1));
        // 除
        System.out.println(big1.divide(big2));
    }
}

4. Java比较器

我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?

16--常用类和基础API--06_第1张图片

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。

Java实现对象排序的方式有两种:

  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator

4.1 自然排序:java.lang.Comparable

Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。

实现 Comparable 的类必须实现 compareTo(Object obj)方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。

public interface Comparable{
    int compareTo(Object obj);
}

实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。

对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。建议(虽然不是必需的)最好使自然排序与 equals 一致

Comparable 的典型实现:(默认都是从小到大排列的)

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
  • Date、Time等:后面的日期时间比前面的日期时间大

4.1.1 举例1

package com.suyv.comparable;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 15:21
*@Description: TODO
*/
public class Student implements Comparable{

    private int id;
    private String name;
    private int score;
    private int age;

    public Student() {
    }

    public Student(int id, String name, int score, int age) {
        this.id = id;
        this.name = name;
        this.score = score;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
        "id=" + id +
        ", name='" + name + '\'' +
        ", score=" + score +
        ", age=" + age +
        '}';
    }

    @Override
    public int compareTo(Object o) {
        // 这些需要强制,将o对象向下转型为Student类型的变量,才能调用Student类中的属性
        // 默认按照学号比较大小
        Student stu = (Student) o;
        return this.id - stu.id;
    }
}

测试类

package com.suyv.comparable;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 15:24
*@Description: TODO
*/
public class StudentTest {
    public static void main(String[] args) {
        Student[] arr = new Student[5];
        arr[0] = new Student(3,"张三",90,23);
        arr[1] = new Student(1,"熊大",99,22);
        arr[2] = new Student(5,"王五",75,25);
        arr[3] = new Student(4,"李四",85,24);
        arr[4] = new Student(2,"熊二",85,18);

        //单独比较两个对象
        System.out.println(arr[0].compareTo(arr[1]));   // 2
        System.out.println(arr[1].compareTo(arr[2]));   // -4
        System.out.println(arr[2].compareTo(arr[2]));   //0

        System.out.println("所有学生:");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("按照学号排序:");
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < arr.length-i; j++) {
                if(arr[j].compareTo(arr[j+1])>0){
                    Student temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

4.1.2 举例2

package com.suyv.comparable;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:05
*@Description: TODO
*/
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;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    //按照价格,比较商品的大小
    @Override
    public int compareTo(Object o) {
        if(o instanceof Goods) {
            Goods other = (Goods) o;
            if (this.price > other.price) {
                return 1;
            } else if (this.price < other.price) {
                return -1;
            }
            return 0;
        }
        throw new RuntimeException("输入的数据类型不一致");
    }
}

测试:

package com.suyv.comparable;

import java.util.Arrays;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:07
*@Description: TODO
*/
public class GoodsTest {
    public static void main(String[] args) {
        Goods[] all = new Goods[4];
        all[0] = new Goods("《红楼梦》", 100);
        all[1] = new Goods("《西游记》", 80);
        all[2] = new Goods("《三国演义》", 140);
        all[3] = new Goods("《水浒传》", 120);

        Arrays.sort(all);

        System.out.println(Arrays.toString(all));
    }
}

4.2 定制排序:java.util.Comparator

思考

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
  • 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?

JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。

  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
public interface Comparator{
    int compare(Object o1,Object o2);
}

4.2.1 举例1

实体类:

上述Student类--无修改

添加一个StudentScore进行分数排序

package com.suyv.comparable;

import java.util.Comparator;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:16
*@Description: 定义定制比较器类
*/
public class StudentScore implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Student s1 = (Student) o1;
        Student s2 = (Student) o2;
        int result = s1.getScore() - s2.getScore();
        return result != 0 ? result : s1.getId() - s2.getId();
    }
}

测试01:使用自然排序

package com.suyv.comparable;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:18
*@Description: TODO
*/
public class StudentTest02 {
    public static void main(String[] args) {

        Student[] arr = new Student[5];
        arr[0] = new Student(3, "张三", 90, 23);
        arr[1] = new Student(1, "熊大", 99, 22);
        arr[2] = new Student(5, "王五", 75, 25);
        arr[3] = new Student(4, "李四", 85, 24);
        arr[4] = new Student(2, "熊二", 85, 18);
        
        System.out.println("所有学生:");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

        System.out.println("按照成绩排序");
        StudentScore sc = new StudentScore();
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < arr.length - i; j++) {
                if (sc.compare(arr[j], arr[j + 1]) > 0) {
                    Student temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

测试02:自然排序和定制排序一起使用

package com.suyv.comparable;

import java.util.Arrays;

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:22
*@Description: TODO
*/
public class StudentTest03 {
    public static void main(String[] args) {
        Student[] students = new Student[5];
        students[0] = new Student(3, "张三", 90, 23);
        students[1] = new Student(1, "熊大", 99, 22);
        students[2] = new Student(5, "王五", 75, 25);
        students[3] = new Student(4, "李四", 85, 24);
        students[4] = new Student(2, "熊二", 85, 18);

        System.out.println(Arrays.toString(students));

        // 自然排序
        Arrays.sort(students);
        System.out.println("使用自然排序");
        System.out.println(Arrays.toString(students));


        //定制排序
        StudentScore sc = new StudentScore();
        Arrays.sort(students, sc);
        System.out.println("使用定制排序");
        System.out.println(Arrays.toString(students));
    }
}

4.2.2 举例2

实体类:

上述Goods类--无修改

测试类:

package com.suyv.comparable;

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

/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-14 16:37
*@Description: TODO
*/
public class GoodsTest01 {
    public static void main(String[] args) {
        Goods[] all = new Goods[4];
        all[0] = new Goods("War and Peace", 100);
        all[1] = new Goods("Childhood", 80);
        all[2] = new Goods("Scarlet and Black", 140);
        all[3] = new Goods("Notre Dame de Paris", 120);

        // 使用匿名内部类
        Arrays.sort(all, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Goods g1 = (Goods) o1;
                Goods g2 = (Goods) o2;
                // 根据名字排序
                return g1.getName().compareTo(g2.getName());
            }
        });

        System.out.println(Arrays.toString(all));
    }
}

补充:Java保留两位小数

1、使用String.format()方法

	@Test
    public void Test01(){
        double number = 3.1455926;
        String result = String.format("%.2f", number);
        System.out.println(result);
    }

2、BigDecimal保留两位小数

	@Test
    public void Test02(){
        double number = 3.1455926;
        BigDecimal decimal = new BigDecimal(number);
        BigDecimal rounded = decimal.setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println(rounded);
    }

3、使用DecimalFormat类

	@Test
    public void Test03(){
        double number = 3.1455926;
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        String result = decimalFormat.format(number);
        System.out.println(result);
    }

你可能感兴趣的:(JavaSE学习记录,java,开发语言)