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类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?

在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);
    }本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!