API<math、date类>

本文详细介绍了Java中的数学API,如Math类的常用方法,以及如何使用BigDecimal和BigInteger进行高精度计算。同时,深入解析了日期时间API的三代变迁,包括LocalDate、LocalTime和ZonedDateTime的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、和数学相关的API
1、java.lang.Math类,它是数学计算的工具类。
   包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
    Math类所有可用的方法都是static修饰的,也就是说我们需要通过“Math.方法”去使用它们。

(1)double Math.random():产生[0,1)的随机数
(2)double Math.sqrt(double x):求x的平方根
(3)double pow(double x, double b):求a的b次方
(4)double ceil(double a):向上取整,结果是double类型
(5)double floor(double a):向下取整,结果是double类型
(6)long round(double a):四舍五入,结果是long类型
(7)int max(int a, int b) :求a和b的最大值,有多种重载形式,即支持多种数据类型
(8)int min(int a, int b) :求a和b的最小值,有多种重载形式,即支持多种数据类型
(9)int abs(int a) :求绝对值,有多种重载形式,即支持多种数据类型

(10)常量:Math.PI圆周率

2、java.math包
(1)BigDecimal:任意精度的定点小数
(2)BigInteger:任意大小的整数

BigDecimal和BigInteger是引用数据类型,又不是包装类,不支持与基本数据类型之间的自动转换。
BigDecimal和BigInteger它们的数据表示,必须new对象。

BigDecimal和BigInteger是引用数据类型,就不能直接使用“运算符”进行计算,需要调用方法来完成计算功能。

当开发中,计算时,参与的数字比较大,或者要求的精度范围比较大,那么可以考虑使用BigDecimal和BigInteger,
而不用double,float,long,int等基本数据类型。

3、java.util.Random:产生随机数
Math.random()产生[0,1)范围的小数

int nextInt():int范围内的任意值
double nextDouble:产生[0,1)范围的小数
int nextInt(int n):在[0,n)范围内产生int随机数

public class TestMath {
    @Test
    public void test6(){
        Random rand = new Random(100); //根据种子,每次运行产生的随机数是一样的
        System.out.println("随机整数:" + rand.nextInt());//-1193959466
        System.out.println("随机整数:" + rand.nextInt(100));//50
        System.out.println("随机小数:" + rand.nextDouble());//0.19497605734770518
    }

    @Test
    public void test5(){
        Random rand = new Random();//没有指定种子,默认种子是和系统时间有关,每次运行结果是不同的
        System.out.println("随机整数:" + rand.nextInt());//1708858262
        System.out.println("随机整数:" + rand.nextInt(100));//29
        System.out.println("随机小数:" + rand.nextDouble());//0.4636514517569357
    }

    @Test
    public void test4(){
        BigDecimal b1 = new BigDecimal("857948515111111.54554744547895111111265475");
        BigDecimal b2 = new BigDecimal("9795862478.2212785851511111154554744547895111111265475851211");

        System.out.println("和:" + b1.add(b2));
        System.out.println("差:" + b1.subtract(b2));
        System.out.println("积:" + b1.multiply(b2));
        //System.out.println("除:" + b1.divide(b2));//java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
        System.out.println("除:" + b1.divide(b2,50,BigDecimal.ROUND_FLOOR));
                                    //87582.74394098036049261626793704997773704251577106577718
        System.out.println("除:" + b1.divide(b2,52,BigDecimal.ROUND_CEILING));
                                    //除:87582.7439409803604926162679370499777370425157710657771878
        System.out.println("余:" + b1.remainder(b2));

    }

    @Test
    public void test3(){
        BigInteger b1 = new BigInteger("85794851511111154554744547895111111265475");
        BigInteger b2 = new BigInteger("97958624782212785851511111154554744547895111111265475");

        System.out.println("和:" + b1.add(b2));
        System.out.println("差:" + b1.subtract(b2));
        System.out.println("积:" + b1.multiply(b2));
        System.out.println("除:" + b1.divide(b2)); //整数/整数,结果只保留整数部分
        System.out.println("余:" + b1.remainder(b2));
        System.out.println("-------------------------------");
        System.out.println("和:" + b2.add(b1));
        System.out.println("差:" + b2.subtract(b1));
        System.out.println("积:" + b2.multiply(b1));
        System.out.println("除:" + b2.divide(b1)); //整数/整数,结果只保留整数部分
        System.out.println("余:" + b2.remainder(b1));

    }
    @Test
    public void test2(){
        System.out.println(Math.ceil(3.6));//4.0
        System.out.println(Math.floor(3.6));//3.0
        System.out.println(Math.round(3.6));//4
        System.out.println("--------------------------");
        System.out.println(Math.ceil(3.3));//4.0
        System.out.println(Math.floor(3.3));//3.0
        System.out.println(Math.round(3.3));//3
    }
    @Test
    public void test1(){
        System.out.println(Math.random());
        System.out.println(Math.sqrt(9.0));
        System.out.println(Math.sqrt(8)); //8自动提升为double

        System.out.println(Math.pow(2,5));//32.0
        System.out.println(Math.pow(2.5, 1.2));//3.002811084953578
    }
}

二、日期时间API
第一代:Date类等
第二代:Calendar等
第三代:LocalDate等

1、java.util.Date类
 Date类的对象 表示特定的瞬间,精确到毫秒。
(1)无参构造:new Date()
(2)无参构造:new Date(毫秒值)
(3)long getTime():返回当前日期时间对象距离1970-1-1 0:0:0 0毫秒的毫秒差值

2、java.util.Calendar类
Calendar类代表日历类型。
Calendar类是抽象类,不能直接创建对象,只能创建子类对象,例如:GregorianCalendar (格里高利日历)子类。
子类GregorianCalendar (格里高利日历)不好记,Calendar提供了一些静态方法:
static Calendar getInstance():使用默认时区和语言环境获得一个日历。
static Calendar getInstance(TimeZone zone, Locale aLocale):使用指定时区和语言环境获得一个日历。

3、Locale:语言环境  和 TimeZone:时区
Java中一切皆对象,把语言环境和时区也用对象表示。

4、java.text.DateFormat:日期时间格式化
DateFormat是抽象类,不能直接new对象,要么通过new直接创建子类对象来使用 或调用 静态方法static DateFormat getDateInstance() 获取子类对象。
直接子类:SimpleDateFormat

DateFormat和SimpleDateFormat只为Date类型提供了支持,没有直接对Calendar类提供支持。

(1)把日期时间对象转为字符串:format方法
(2)把字符串转为日期时间对象:parse方法

SimpleDateFormat类中定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):

字母  日期或时间元素  表示  示例
G  Era 标志符  Text  AD
y  年  Year  1996; 96
M  年中的月份  Month  July; Jul; 07
w  年中的周数  Number  27
W  月份中的周数  Number  2
D  年中的天数  Number  189
d  月份中的天数  Number  10
F  月份中的星期  Number  2
E  星期中的天数  Text  Tuesday; Tue
a  Am/pm 标记  Text  PM
H  一天中的小时数(0-23)  Number  0
k  一天中的小时数(1-24)  Number  24
K  am/pm 中的小时数(0-11)  Number  0
h  am/pm 中的小时数(1-12)  Number  12
m  小时中的分钟数  Number  30
s  分钟中的秒数  Number  55
S  毫秒数  Number  978
z  时区  General time zone  Pacific Standard Time; PST; GMT-08:00
Z  时区  RFC 822 time zone  -0800

5、JDK1.8引入了第三代日期时间API
因为原来的第一代和第二代用起来很麻烦,而且有一些问题:
(1)日期时间对象可变。正常逻辑中,某个日期时间对象,就应该代表某个固定的日期时间值。
            例如:c1对象  对应   2021-8-18日期
                2009-1-18应该用另个一Calendar对象表示。
(2)偏移性:Date中的年份是从1900开始的,而月份都是从0开始的。
(3)格式化只对Date有用,Calendar则不行。
(4)此外,它们也不是线程安全的,不能处理闰秒等。

JDK1.8在如下包中,增加了第三代的日期时间API:
* java.time – 包含值对象的基础包
* java.time.chrono – 提供对不同的日历系统的访问。
* java.time.format – 格式化和解析时间和日期
* java.time.temporal – 包括底层框架和扩展特性
* java.time.zone – 包含时区支持的类

6、第三代日期时间API中常用的类型
(1)本地日期时间:LocalDate、LocalTime、LocalDateTime
A:now()获取系统日期或时间
B:of()
C:plusXxx
D:minusXxx
E:isLeapYear():判断是否闰年
F:getXXX

注意:1.8的第三代的日期时间对象是不可变的,修改以后,需要用变量重新接收,否则原来变量仍然表示原来的对象。

(2)指定时区日期时间:ZondId和ZonedDateTime

(3)持续日期/时间:Period和Duration
Period:日期间隔
Duration:时间间隔

(4)DateTimeFormatter:日期时间格式化
A:DateTimeFormatter.常量字段
  例如:DateTimeFormatter.ISO_DATE_TIME

B:  FormatStyle枚举类型指定的常量对象:LONG,MEDIUM,SHORT
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);

C:配合y,M,D,d等模式来使用
DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss SSS毫秒 这是这一年的第D天,这一天是E");

public class TestDate {
    @Test
    public void test21() {
        LocalDateTime now = LocalDateTime.now();
//        DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);//FULL对于时间来说,必须有时区信息在里面
//        System.out.println(df1.format(now));//异常

        DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(df1.format(now));//2021年8月18日 星期三 下午02时36分56秒 CT
    }

    @Test
    public void test20() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);//2021-08-18T14:09:56.679

        DateTimeFormatter d1 = DateTimeFormatter.ISO_DATE_TIME;
        DateTimeFormatter d2 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        System.out.println(d1.format(now));//2021-08-18T14:10:34.587
        System.out.println(d2.format(now));//2021-08-18T14:10:34.587

        ZonedDateTime time = ZonedDateTime.now(ZoneId.of("America/Toronto"));
        System.out.println(d1.format(time));//2021-08-18T02:29:48.845-04:00[America/Toronto]
        System.out.println(d2.format(time));//2021-08-18T02:29:48.845
    }

        @Test
    public void test19() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);//2021-08-18T14:09:56.679

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;
        System.out.println(dateTimeFormatter.format(now));//2021-08-18T14:10:34.587

        DateTimeFormatter df1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        System.out.println(df1.format(now));//2021年8月18日 下午02时11分52秒

        DateTimeFormatter df2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
        System.out.println(df2.format(now));//2021-8-18 14:12:34

        DateTimeFormatter df3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
        System.out.println(df3.format(now));//21-8-18 下午2:12

        DateTimeFormatter smiple = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss SSS毫秒 这是这一年的第D天,这一天是E");
        System.out.println(smiple.format(now));//2021年08月18日 14:14:56 409毫秒 这是这一年的第230天,这一天是星期三
    }
    @Test
    public void test18() {
        LocalTime now = LocalTime.now();
        LocalTime ye = LocalTime.of(23,59,59);
        Duration d = Duration.between(now,ye);
        System.out.println(d);//PT9H51M3.908S
    }
    @Test
    public void test17() {
        LocalDate today = LocalDate.now();

        LocalDate dan = LocalDate.of(2022, 1, 1);

        Period p = Period.between(today,dan );
        System.out.println(p);//P4M14D
        System.out.println(p.getDays());//14
        System.out.println(p.getMonths());//4
        System.out.println(p.getYears());//0
    }

    @Test
    public void test16() {
        ZonedDateTime localTime = ZonedDateTime.now();
        System.out.println(localTime);//2021-08-18T14:02:02.005+08:00[Asia/Shanghai]

        ZonedDateTime time = ZonedDateTime.now(ZoneId.of("America/Toronto"));
        System.out.println(time);//2021-08-18T02:03:31.194-04:00[America/Toronto]
    }

    @Test
    public void test15() {
        LocalDate date = LocalDate.of(2020, 7, 28);
        System.out.println(date.getYear());//2020
        System.out.println(date.getMonth());//JULY
        System.out.println(date.getMonthValue());//7
        System.out.println(date.getDayOfMonth());//28
    }


    @Test
    public void test14() {
        LocalDate date = LocalDate.of(2020, 7, 28);
        System.out.println(date.isLeapYear());//true
    }
    @Test
    public void test13() {
        LocalDate kai = LocalDate.of(2021, 7, 28);
        System.out.println(kai);

        LocalDate future = kai.plusDays(200);
        System.out.println(future);//2022-02-13
    }
    @Test
    public void test12() {
        LocalDate kai = LocalDate.of(2021, 7, 28);
        System.out.println(kai);//2021-07-28

        LocalTime time = LocalTime.of(9,0,0);
        System.out.println(time);//09:00

        LocalDateTime t = LocalDateTime.of(2021, 7, 28,9,0,0);
        System.out.println(t);//2021-07-28T09:00
    }

    @Test
    public void test11() {
        LocalDate today = LocalDate.now();
        System.out.println(today);//2021-08-18

        LocalTime now = LocalTime.now();
        System.out.println(now);//11:56:38.947

        LocalDateTime t = LocalDateTime.now();
        System.out.println(t);//2021-08-18T11:57:10.718
    }

    @Test
    public void test10() {
        Calendar c1 = Calendar.getInstance();
        System.out.println("年份:" + c1.get(Calendar.YEAR));//2021
        System.out.println("月份:" + (c1.get(Calendar.MONTH) +1 ));//8
        System.out.println("日:" + c1.get(Calendar.DATE ));//18
        //2021-8-18

        c1.set(Calendar.YEAR, 2008);
        c1.set(Calendar.MONTH, 12); //月份正常值是[0,11]
        System.out.println("年份:" + c1.get(Calendar.YEAR));//2009
        System.out.println("月份:" + (c1.get(Calendar.MONTH) +1 ));//1
        System.out.println("日:" + c1.get(Calendar.DATE ));//18
        //2009-1-18
    }
    @Test
    public void test09() {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入生日(格式:1990-8-6):");
        String birth = input.next();

        try {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = sf.parse(birth );

            SimpleDateFormat sf2 = new SimpleDateFormat("出生当天是这一年的第D天");
            System.out.println(sf2.format(date));//出生当天是这一年的第218天
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Test
    public void test08() {
        Date d = new Date();

        SimpleDateFormat sf = new SimpleDateFormat();
        System.out.println(sf.format(d));//21-8-18 上午11:37

        SimpleDateFormat sf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS毫秒 这是这一年的第D天,这一天是E");
        System.out.println(sf2.format(d));//2021年08月18日 11:40:25 485毫秒 这是这一年的第230天,这一天是星期三
    }
    @Test
    public void test07() {
        Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone("America/Toronto"),Locale.CANADA); //加拿大多伦多
        System.out.println(c1);
        System.out.println("年份:" + c1.get(Calendar.YEAR));//2021
        System.out.println("月份:" + (c1.get(Calendar.MONTH) +1 ));//8
        System.out.println("日:" + c1.get(Calendar.DATE ));//17
        System.out.println("时:" + c1.get(Calendar.HOUR));//11  12小时制
        System.out.println("时:" + c1.get(Calendar.HOUR_OF_DAY));//23 24小时制度
        System.out.println("分:" + c1.get(Calendar.MINUTE));//32
        System.out.println("秒:" + c1.get(Calendar.SECOND));//18
    }
    @Test
    public void test06() {
        Locale china1 = Locale.CHINA;
        Locale china2 = new Locale("zh","CN");

        TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");

        String[] availableIDs = TimeZone.getAvailableIDs();//获取所有时区的ID
        for (int i = 0; i < availableIDs.length; i++) {
            System.out.println(availableIDs[i]);
        }
    }

    @Test
    public void test05(){
        Calendar c1 = Calendar.getInstance();
        System.out.println(c1);
        /*
        ...
        YEAR=2021,
        MONTH=7,                    月份从0开始
        WEEK_OF_YEAR=34,
        WEEK_OF_MONTH=3,
        DAY_OF_MONTH=18,
        DAY_OF_YEAR=230,
        DAY_OF_WEEK=4,              周日是一个星期的第1天
        DAY_OF_WEEK_IN_MONTH=3,
        AM_PM=0,
        HOUR=11,
        HOUR_OF_DAY=11,
        MINUTE=22,
        SECOND=27,
        MILLISECOND=262
         */

        System.out.println("年份:" + c1.get(Calendar.YEAR));//2021
        System.out.println("月份:" + (c1.get(Calendar.MONTH) +1 ));//8
    }

    @Test
    public void test04(){
//        Calendar c1 = new Calendar() ;//错误,因为Calendar是抽象类
        Calendar c1 = new GregorianCalendar();
    }

    @Test
    public void test03(){
        long time = Long.MAX_VALUE;
        Date d2 = new Date(time);
        System.out.println(d2);//Sun Aug 17 15:12:55 CST 292278994
    }

    @Test
    public void test02(){
        long time = Integer.MAX_VALUE;
        Date d2 = new Date(time);
        System.out.println(d2);//Mon Jan 26 04:31:23 CST 1970
    }
    @Test
    public void test01(){
        Date d1 = new Date();
        System.out.println(d1);
        //Wed Aug 18 11:12:57 CST 2021
        //Date类的toString方法,没有显示毫秒值

        long time = d1.getTime();//返回当前日期时间对象,对应的毫秒值
        System.out.println(time);//1629256449466  距离1970-1-1 0:0:0 0毫秒的毫秒差值
    }
}

三、数组工具类
1、回忆之前学习的数组的算法
(1)在数组中找最大值
(2)在数组中找最大值及其下标
(3)在数组中查找某个元素是否存在,并返回下标
A:顺序查找
B:二分查找
(4)统计分析数组中的元素情况
A:求总和
B:找偶数的个数
C:找3的倍数的个数
...
(5)冒泡排序

ublic class TestArray {
    @Test
    public void test17() {
        int[] arr = {2, 4, 5, 1, 6};
        System.out.println(Arrays.toString(arr));//[2, 4, 5, 1, 6]
    }

    @Test
    public void test16() {
        Student[] arr = new Student[3];
        arr[0] = new Student(2,"张三",78);
        arr[1] = new Student(1,"李四",98);
        arr[2] = new Student(3,"王五",60);

        Arrays.sort(arr,new 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 ? s1.getId() - s2.getId() : result;
            }
        });//传入一个Comparator的实现类,重写compare方法

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i] );
        }
    }

    @Test
    public void test15() {
        Student[] arr = new Student[3];
        arr[0] = new Student(2,"张三",78);
        arr[1] = new Student(1,"李四",98);
        arr[2] = new Student(3,"王五",60);

        Arrays.sort(arr);//要求Student类实现Comparable接口,重写compareTo方法

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i] );
        }
    }

    @Test
    public void test14() {
        int[] arr = {2, 4, 5, 1, 6};
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
        @Test
    public void test13() {
        int[] arr = new int[5];
        Arrays.fill(arr, -1);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
    @Test
    public void test12() {
        int[] arr1 = {1, 6, 9, 12, 67};
        int[] arr2 = {1, 6, 9, 12, 67, 34};
        System.out.println(Arrays.equals(arr1, arr2));
    }
    @Test
    public void test11() {
        int[] arr = {1, 6, 9, 12, 67};
        int[] newArr1 = Arrays.copyOfRange(arr,2,8);
        for (int i = 0; i < newArr1.length; i++) {
            System.out.print(newArr1[i] + " ");
        }
        System.out.println();//9 12 67
    }
    @Test
    public void test10() {
        int[] arr = {1, 6, 9, 12, 67};
        int[] newArr1 = Arrays.copyOf(arr, 3);
        for (int i = 0; i < newArr1.length; i++) {
            System.out.print(newArr1[i] + " ");
        }
        System.out.println();

        int[] newArr2 = Arrays.copyOf(arr, 5);
        for (int i = 0; i < newArr2.length; i++) {
            System.out.print(newArr2[i] + " ");
        }
        System.out.println();

        int[] newArr3 = Arrays.copyOf(arr, 10);
        for (int i = 0; i < newArr3.length; i++) {
            System.out.print(newArr3[i] + " ");
        }
        System.out.println();
    }

    @Test
    public void test09() {
        int[] arr = {1, 6, 9, 12, 67};//数组必须有序
        int target = 12;
        int index = Arrays.binarySearch(arr, target);
        if(index < 0){
            System.out.println(target +"不存在");
        }else{
            System.out.println(target+"在[" +index +"]位置");
        }
    }

     @Test
    public void test08() {
        int[] arr = {2, 4, 5, 1, 6};

        //冒泡排序
        for(int i=1; i<arr.length; i++){
            for(int j=0; j<arr.length-i; j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }

        //遍历结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
    @Test
    public void test07() {
        int[] arr = {1, 6, 9, 12, 67};
        
        //统计偶数的个数
        int count = 0;
        for (int i=0; i<arr.length; i++){
            if(arr[i]%2==0){
                count++;
            }
        }
        System.out.println("count = " + count);
    }
    
    @Test
    public void test06(){
        int[] arr = {1,6,9,12,67};//数组必须有序
        int target = 1;//查找目标
        int index = -1;

        //二分查找
        for(int left=0,right=arr.length-1; left<=right;){
            int mid = left + (right-left)/2; //mid = (left+right)/2;
            if(arr[mid] == target){
                index = mid;
                break;
            }else if(target < arr[mid]){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        
        if(index == -1){
            System.out.println(target +"不存在");
        }else{
            System.out.println(target+"在[" +index +"]位置");
        }
    }

    @Test
    public void test05(){
       String[] strings = {"hello","java","world"};

       //顺序查找
        String target = "张三";
        int index = -1;
        for (int i = 0; i < strings.length; i++) {
            if(strings[i].equals(target)){
                index = i;
                break;
            }
        }
        if(index == -1){
            System.out.println(target +"不存在");
        }else{
            System.out.println(target+"在[" +index +"]位置");
        }
    }


    @Test
    public void test04(){
        int[] arr = {2,4,5,1,6};

        //顺序查找
//        int target = 3;//查找目标
        int target = 1;//查找目标
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                index = i;
                break;
            }
        }
        if(index == -1){
            System.out.println(target +"不存在");
        }else{
            System.out.println(target+"在[" +index +"]位置");
        }
    }


    @Test
    public void test03(){
        int[] arr = {2,4,5,1,6};

        //找最大值及其下标
        int maxIndex = 0;//假设第一个最大
        for(int i=1; i<arr.length; i++){
            if(arr[i] > arr[maxIndex]){
                maxIndex = i;
            }
        }
        System.out.println("max = " + arr[maxIndex]);
        System.out.println("最大值下标index = " + maxIndex);
    }

    @Test
    public void test02(){
        int[] arr = {2,4,5,1,6};

        //找最大值及其下标
        int max = arr[0];//假设第一个最大
        int index = 0;
        for(int i=1; i<arr.length; i++){
            if(arr[i] > max){
                max = arr[i];
                index = i;
            }
        }
        System.out.println("max = " + max);
        System.out.println("最大值下标index = " + index);
    }

    @Test
    public void test01(){
        int[] arr = {2,4,5,1,6};

        //找最大值
        int max = arr[0];//假设第一个最大
        for(int i=1; i<arr.length; i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        System.out.println("max = " + max);
    }
}

class Student implements Comparable {
    private int id;
    private String name;
    private int score;

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

    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;
    }

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

    @Override
    public int compareTo(Object o) {
        return this.id - ((Student)o).id;
    }
}

2、数组工具类:java.util.Arrays
它里面的方法都是静态的,可以完成数组的各种运算:
(1)public static int binarySearch(int[] a, int key)  :使用二分查找法,在数组中查找目标
(2)public static int[] copyOf(int[] original,int newLength):复制一个新数组,新数组的长度为newLength
(3)public static int[] copyOfRange(int[] original, int from, int to):复制一个新数组,新数组的长度为(to-from)
    左闭右开,[from ,to)
(4)public static boolean equals(int[] a,  int[] a2):比较两个数组是否长度和内容一致
(5)public static void fill(int[] a,int val):用val填充整个数组
(6)public static void sort(int[] a)  :排序
  public static void sort(Object[] a) :自然排序
 public static  void sort(Object[] a, Comparator c)  :定制排序
(7)public static String toString(int[] a):返回数组的元素列表,[元素1,元素2...]

3、补充
(1)数组的反转
方案一:首尾交换
方案二:借助一个新数组,倒着放元素

推荐用方案一:时空消耗低

(2)数组元素的插入
(3)数组元素的删除
(4)直接选择排序

public class TestArray2 {
    @Test
    public void test07(){
        int[] arr = {49,38,65,97,76,13,27,49};
        /*
        直接选择排序
        思路:每一轮找出本轮“未排序”元素的最小/大值,把它放到它应该在的位置,经过多轮后实现整体排序
        例如:{49,38,65,97,76,13,27,49}
        第一轮:找出本轮“未排序”元素的最小值  13, 它应该在[0]位置  交换13和arr[0]
             {13,38,65,97,76,49,27,49}
         第二轮: 找出本轮“未排序”元素的最小值  27,它应该在[1]位置  交换27和arr[1]
             {13,27,65,97,76,49,38,49}
         第三轮: 找出本轮“未排序”元素的最小值  38,它应该在[2]位置  交换38和arr[2]
            {13,27,38,97,76,49,65,49}
          第四轮: 找出本轮“未排序”元素的最小值  49(假设是前面49),它应该在[3]位置  交换49和arr[3]
            {13,27,38,49,76,97,65,49}
          第五轮: 找出本轮“未排序”元素的最小值  49(假设是后面49),它应该在[4]位置  交换49和arr[4]
            {13,27,38,49,49,97,65,76}
        第六轮: 找出本轮“未排序”元素的最小值  65,它应该在[5]位置  交换49和arr[5]
            {13,27,38,49,49,65,97,76}
         第七轮: 找出本轮“未排序”元素的最小值  76,它应该在[6]位置  交换76和arr[5]
            {13,27,38,49,49,65,76,97}
            n个元素,需要n-1轮
         */
        for(int i=0; i<arr.length-1; i++){
            //找出本轮“未排序”元素的最小值,及其位置
            int min = arr[i];
            int index = i;
            for(int j=i+1; j<arr.length; j++){
                if(arr[j] < min){
                    min = arr[j];
                    index = j;
                }
            }
            System.out.println("本轮最小值是" + min +",它的位置是[" + index + "]");

            //把最小值放到正确的位置[i]
            if(index != i){
                int temp = arr[index];
                arr[index ] = arr[i];
                arr[i] = temp;
            }
            System.out.println("第"+ (i+1)+"轮结果:" +Arrays.toString(arr));
        }

    }

    @Test
    public void test06() {
        String[] arr = {"hello","java","atguigu","chai","mysql"};

        //删除arr[2]位置的元素
        //方案二:把删除位置的后面的元素前移
        System.arraycopy(arr,3, arr,2,2);
        System.out.println(Arrays.toString(arr));//[hello, java, chai, mysql, mysql]

        //然后把最后的位置置空
        arr[4] = null;
        System.out.println(Arrays.toString(arr));//[hello, java, chai, mysql, null]
        /*
        这种方案,元素被删掉了,后期想要给这个数组增加新元素时,不需要遍历数组,直接放后面即可,对于后续操作来说更快更高薪
         */
    }

    @Test
    public void test05() {
        String[] arr = {"hello","java","atguigu","chai","mysql"};

        //删除arr[2]位置的元素
        //方案一:直接把arr[2] 赋值为null
        arr[2] = null;
        System.out.println(Arrays.toString(arr));

        //这种方案,元素被删掉了,但是后期想要给这个数组增加新元素时,就需要数组,找空位
        //类似于:停车场  ,车走了,新的车来了,需要绕停车场找位置,麻烦
    }
    @Test
    public void test04() {
        int[] arr = {1, 2, 3, 4, 5};

        //假如,要在arr数组的[2]位置插入一个新元素6,怎么做
        //(1)如果原来的数组是“满”,需要先扩容
       arr = Arrays.copyOf(arr, arr.length+1); //增加一个位置
        System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5, 0]

        //(2)把[2]位置及其后面的元素后移
        System.arraycopy(arr,2,arr,3,3);
        System.out.println(Arrays.toString(arr));//[1, 2, 3, 3, 4, 5]

        //(3)把新元素6放到arr[2]
        arr[2] = 6;
        System.out.println(Arrays.toString(arr));//[1, 2, 6, 3, 4, 5]
    }

    @Test
    public void test03() {
        int[] arr = {1, 2, 3, 4, 5};

        //数组反转
        //思路二:借助一个新数组,把原来arr的元素倒着放到temp中
        int[] temp = new int[arr.length];
        for(int i=0; i<temp.length; i++){
            temp[i] = arr[arr.length-1-i];
        }

        //让arr指向temp新数组
        arr = temp;
        System.out.println(Arrays.toString(arr));
    }


    @Test
    public void test02(){
        int[] arr = {1,2,3,4,5};

        //数组反转
        //思路:首尾交换
        for(int i=0; i<arr.length; i++){//交换的次数,如果是4次,就又换回去了
            int temp = arr[i];
            arr[i] = arr[arr.length-1-i];
            arr[arr.length-1-i] = temp;
        }

        System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5]
    }

    @Test
    public void test01(){
        int[] arr = {1,2,3,4,5};

        //数组反转
        //思路一:首尾交换
        for(int i=0; i<arr.length/2; i++){//交换的次数
            int temp = arr[i];
            arr[i] = arr[arr.length-1-i];
            arr[arr.length-1-i] = temp;
        }

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

四、系统信息相关的API
1、java.lang.Runtime
Runtime:运行时环境对象,代码当前JVM的运行环境

Runtime对象是不能自己new的,通过静态方法getRuntime()获取。
Runtime的构造器是私有化的,在Runtime的内部有一个静态变量,来存储Runtime的对象,在Runtime内部创建了它的唯一的对象。
这个设计是单例(唯一的实例对象)设计。

可以获取内存信息等,例如:totalMemory()和freeMemory()
调用gc()方法通知GC工作。

2、java.lang.System类
System 类包含一些有用的类字段和方法。它不能被实例化。

(1)Java的常量字段:
out:普通信息的输出流,默认输出到控制台,如果重新set了,就不一定 打印到控制台
err:标准的错误输出流,默认输出到控制台,如果重新set了,就不一定 打印到控制台
in:默认代码键盘输入,如果重新set了,就不一定从键盘输入信息

public final static PrintStream out = null;
public final static PrintStream err = null;
public final static InputStream in = null;

为什么out,err,in的常量对象没有大写?
这些out,err,in在Java层面看起来是常量对象,因为有final修饰,
但是System类中却给他们提供了set方法进行修改。
正常情况下,final修饰成员变量是没有set方法的。

public static void setIn(InputStream in){...}
public static void setOut(PrintStream out){...}
public static void setErr(PrintStream err){...}

private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);

System类中要修改out,err,in对象是通过C底层的代码完成的,在Java层面做不了。

(2)System.exit(0).退出JVM,根据惯例,非 0 的状态码表示异常终止。
(3)gc():通知GC工作。
(4)Properties getProperties() :获取系统属性
(5)static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)  :复制数组
    参数1:src代表的是原数组
    参数2:srcPos代表的是原数组开始复制起始下标
    参数3:dest代表的是目标数组
    参数4:destPos代表的是目标数组开始接收复制元素的起始下标
    参数5:一共复制几个元素

    对于接下来学习Arrays工具类还有集合源码等来说非常重要。

public class TestRuntimeAndSystem {
    @Test
    public void test08(){
        int[] arr = {1,2,3,4,5,6,7,8};
        System.arraycopy(arr,3,arr,2,5);
        /*
        这个arraycopy方法非常智能,当发现是同一个数组内部从后往前复制时,会从需要复制的元素第一个开始复制
        arr[3]->arr[2]
        arr[4]->arr[3]
        arr[5]->arr[4]
        arr[6]->arr[5]
        arr[7]->arr[6]
         */
        //遍历arr1
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        //原:1,2,3,4,5,6,7,8
        //现:1 2 4 5 6 7 8 8
    }

    @Test
    public void test07(){
        int[] arr = {1,2,3,4,5,6,7,8};
        System.arraycopy(arr,0,arr,1,7);
        /*
        这个arraycopy方法非常智能,当发现是同一个数组内部从前往后复制时,会从需要复制的元素最后一个开始复制
        arr[6]->arr[7]
        arr[5]->arr[6]
        arr[4]->arr[5]
        arr[3]->arr[4]
        arr[2]->arr[3]
        arr[1]->arr[2]
        arr[0]->arr[1]
         */
        //遍历arr1
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        //1,2,3,4,5,6,7,8
        //1 1 2 3 4 5 6 7
    }
    @Test
    public void test06(){
        int[] arr = {1,2,3,4,5,6,7,8};
        //arr数组内部复制
        //从arr[0]开始复制,arr[0]放到arr[3],依次类推,一共复制4个元素
        System.arraycopy(arr,0,arr,3,4);
        /*
        这个arraycopy方法非常智能,当发现是同一个数组内部从前往后复制时,会从需要复制的元素最后一个开始复制
        arr[3] -> arr[6]
        arr[2] -> arr[5]
        arr[1] -> arr[4]
        arr[0] -> arr[3]
         */
        //遍历arr1
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");//1 2 3 1 2 3 4 8
        }
        //原:1 2 3 4 5 6 7 8

        //现:1 2 3 1 2 3 4 8
    }
    @Test
    public void test05(){
        int[] arr1 = new int[10];
        int[] arr2 = {1,2,3,4,5};
        //把arr2数组的元素复制到arr1中,把arr2从[0]位置开始复制,放到arr1中从[3]位置开始放,一共复制3个元素

        System.arraycopy(arr2,0,arr1,3,3);

        //遍历arr1
        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);
        }/*
            0,0,0,1,2,3,0,0,0,0
            */
    }
    @Test
    public void test04(){
        Properties properties = System.getProperties();
        System.out.println(properties);
    }
    @Test
    public void test03(){
        System.out.println("hello");//普通信息的输出流   println方法不是System类的是out对象,out对象是java.io.PrintStream类型
        System.err.println("java");//标准的错误输出流
        Scanner input = new Scanner(System.in); //默认代码键盘输入

        input.close();//按照规范来说,使用完输入流之后,需要关闭IO流
    }

    @Test
    public void test02(){
        Runtime.getRuntime().gc();//通知GC可以来回收一下内存垃圾,但是不代表GC立刻开始工作。
        /*
        特别是早期GC回收器,它会“stop the world"然后开始回收垃圾。
        GC工作时,会让Java程序其他的代码停下来,等待GC工作完。
        后期的JDK版本的GC回收器有优化,和Java程序并行。
        高级部分再将GC算法。
         */
    }
    @Test
    public void test01(){
        Runtime runtime = Runtime.getRuntime();

        System.out.println("OS给JVM分配的总内存:" + runtime.totalMemory());//512753664
        System.out.println("JVM中空闲内存:" + runtime.freeMemory());//499328232
    }
}

class MyClass{
    private static final int a = 1;//没有set方法

    public static int getA() {
        return a;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值