JAVA基础篇——常用API二

十、常用API

不要重复造轮子

1. Object类

Java中所有类的对象都可以直接使用Object类中提供的一些方法。

常见方法:

public String toString()——返回对象的字符串表示形式

作用: 返回对象的字符串形式

意义: 让子类重写,以便返回子类对象的内容

public boolean equals(Object o)——判断两个对象是否相等

作用: 判断两个对象的地址是否相同

意义: 让子类重写,以便比较两个对象的内容是否相同

protected Object clone()——对象克隆

作用: 当某个对象调用这个方法时,这个方法会复制一个一摸一样的新对象返回

2. Objects类——工具类,有很多操作对象的静态方法以供使用,static实用 程序方法

常见方法:

public static boolean equals(Object a, Object b)——先做非空判断,再比较两个对象,内部做了非空校验

public static boolean isNull(Object obj)——判断对象是否为null,为null返回true

public static boolean nonNull(Object obj)——判断对象是否不为null,不为null返回true

public class Test {
    public static void main(String[] args) {
        String s1 = null;
        String s2 = "itheima";
        // System.out.println(s1.equals(s2)); // 会报空指针错误,调用不了了
        System.out.println(s2.equals(s1)); // false
        System.out.println(Objects.equals(s1, s2));  // false

        System.out.println(Objects.isNull(s1));  // true
        System.out.println(Objects.isNull(s2));  // false
        
        System.out.println(Objects.nonNull(s1));  // false
        System.out.println(Objects.nonNull(s2));  // true
    }
}

3. 包装类

把基本类型的数据包装成对象

泛型和集合中不支持基本数据类型,只支持引用数据类型。

数转字符串:包装类.toString(str)

字符串转数:包装类.valueOf(num)

public class Test {
    public static void main(String[] args) {
        // Integer a1 = new Integer(12); // 已过时
        Integer a2 = Integer.valueOf(12);
        System.out.println(a2);

        // 自动装箱机制:把基本类型的数据转换成对象
        Integer a3 = 12;

        // 自动拆箱:自动把包装类型的对象转换成对应的基本数据类型
        int a4 = a3;

        // 方法
        // 1. 把基本类型的数据转换成字符串
        Integer a = 23;
        String rs1 = Integer.toString(a);
        System.out.println(rs1 + 4);  // 234

        String rs2 = Objects.toString(23);
        System.out.println(rs2 + 1);  // 231

        // 更优雅的做法
        String rs3 = a + "";
        System.out.println(rs3 + 6);  // 236

        // 2. 把字符串类型的数值转换成对应的基本类型——重要
        String ageStr = "29";
//        int age = Integer.parseInt(ageStr);
        int age = Integer.valueOf(ageStr);
        System.out.println(age + 1);  // 30
    }
}

4. StringBuilder

可变的字符序列,字符串拼接、修改等(用来操作字符串的)

StringBuilder比String更适合做字符串的修改

常用方法:

  1. 构造器:
  • public StringBuilder()
  • public StringBuilder(String str)
  1. 方法:
  • public StringBulider append(任意类型):添加数据并返回对象本身
  • public StringBulider reverse():将对象的内容反转
  • public int length():返回对象类型的长度
  • public String toString():把StringBuilder转换为String
public class Test {
    public static void main(String[] args) {
        StringBuilder s = new StringBuilder();
        StringBuilder s1 = new StringBuilder("itheima");

        // 1. 拼接操作
        s1.append("黑马");
        s1.append('a');
        s1.append(888);
        System.out.println(s1);

        // 2. 反转操作
        s1.reverse();
        System.out.println(s1);

        // 3. 返回对象长度
        System.out.println(s1.length());

        // 4. 返回String类型的变量
        String s2 = s1.toString();
        System.out.println(s2);
    }
}

为什么操作字符串建议使用StringBuilder,而不是String?

  • String频繁拼接、修改使用StringBuilder,效率更高
  • 但是定义一些字符串变量的情况,String效率更高

5. StringBuffer

与StringBuilder用法一样,但是StringBuilder线程是不安全的,StringBuffer线程是安全的

6. StringJoiner

原因: 拼接操作String太慢,StringBuilder太麻烦。

概念: 同上,但JDK8开始才有的

好处: 代码高效简洁

public class Test3 {
    public static void main(String[] args) {
        // 只有间隔符的构造器
        StringJoiner s = new StringJoiner(",");
        s.add("java1");
        s.add("java2");
        s.add("java3");
        System.out.println(s);  //java1,java2,java3

        // 有间隔符、开始符号、结束符号的有参构造器
        StringJoiner s1 = new StringJoiner(",", "[", "]");
        s1.add("y");
        s1.add("x");
        s1.add("g");
        System.out.println(s1.length());  // 7
        String s2 = s1.toString();
        System.out.println(s2);  //[y,x,g]

        // 调用方法
        System.out.println(getArrayData(new int[]{1, 2, 3}));
    }

    public static String getArrayData(int[] arr) {
        // 1. 判断arr是否为null
        if (arr == null) {
            return null;
        }
        StringJoiner ss = new StringJoiner(",", "[", "]");
        for (int i = 0; i < arr.length; i++) {
            ss.add(arr[i] + "");
        }
        return ss.toString();
    }
}

7. Math

数学工具类,对数据进行操作的静态方法

public class MathTest {
    public static void main(String[] args) {
        // abs()得到绝对值
        System.out.println(Math.abs(-12.3));
        System.out.println(Math.abs(1));

        // 向上取整
        System.out.println(Math.ceil(1.0));  // 1.0
        System.out.println(Math.ceil(1.00000001));  // 2.0

        // 向下取整
        System.out.println(Math.floor(4.9999));  // 4.0
        System.out.println(Math.floor(4.0000));  // 4.0

        // 四舍五入
        System.out.println(Math.round(3.49999));  // 3
        System.out.println(Math.round(3.50000));  // 4

        // 取最值
        System.out.println(Math.max(10, 20));  // 20
        System.out.println(Math.min(10, 20));  // 10

        // 取次方
        System.out.println(Math.pow(2, 3)); // 8.0

        // 取随机数,[0.0, 1.0)
        System.out.println(Math.random());  // 0.805434885364831
    }
}

8. System

代表程序所在的系统,也是一个工具类

public class SystemTest {
    public static void main(String[] args) {
        // 终止当前运行的Java虚拟机
        // System.exit(0);
        System.out.println("--");

        // 获取当前系统的时间,从1970年1月1日 0:0:0开始计算——前后计算差得到程序运行时间,程序性能分析
        long time = System.currentTimeMillis();
        System.out.println(time);
    }
}

9. Runtime

Java程序所在的运行环境

单例类:对外只需要一个对象

public class RuntimeTest {
    public static void main(String[] args) throws IOException, InterruptedException {
        // 得到运行时对象
        Runtime r = Runtime.getRuntime();
        // 终止当前运行的虚拟机,该参数用作状态代码。非零状态表示异常终止
//        r.exit(0);
        // 获取虚拟机能够使用的处理器数
        System.out.println(r.availableProcessors());  // 12
        // 获取虚拟机的内存总数,long字节
        System.out.println(r.totalMemory());
        // 返回Java虚拟机中的可用内存量
        System.out.println(r.freeMemory());
        // 启动某个程序,并返回代表该程序的对象
        Process p = r.exec("D:\\Zhiyun\\ZhiyunTranslator\\ZhiYunTranslator.exe");

        Thread.sleep(5000);

        p.destroy();
    }
}

10. BigDecimal

开发中经常遇到,要掌握

概念: 解决浮点运算时,会出现结果失真

public class BigDecimalDemo1 {
    public static void main(String[] args) {
        // 浮点数运算失真,不是每种情况下都会失真??why
//        double a = 0.1;
//        double b = 0.3;
//        double c = a + b;
//        System.out.println(c);  // 0.4
        double a = 0.1;
        double b = 0.2;
        double c = a + b;
        System.out.println(c);  // 0.30000000000000004

        // 解决失真问题
        // 1. 先变成字符串,再封装成BigDecimal对象
//        BigDecimal a1 = new BigDecimal(Double.toString(a));
//        BigDecimal b1 = new BigDecimal(Double.toString(b));
        BigDecimal a1 = BigDecimal.valueOf(a);  // 相当于上一行代码的封装
        BigDecimal b1 = BigDecimal.valueOf(b);

//        // 计算+
//        BigDecimal c1 = a1.add(b1);
//        System.out.println(c1);  // 0.3

//        // 计算-
//        BigDecimal c1 = a1.subtract(b1);
//        System.out.println(c1);  // -0.1

//        // 计算*
//        BigDecimal c1 = a1.multiply(b1);
//        System.out.println(c1);  // 0.02

        // 计算/
        BigDecimal c1 = a1.divide(b1);
        System.out.println(c1);  // 0.5

        // 除不尽的情况
        BigDecimal i = BigDecimal.valueOf(0.1);
        BigDecimal j = BigDecimal.valueOf(0.3);
//        BigDecimal k = i.divide(j);  //Non-terminating decimal expansion; no exact representable decimal result.
//        BigDecimal k = i.divide(j, 2);  // 默认是向上取保留一位小数
        BigDecimal k = i.divide(j, 2, RoundingMode.HALF_UP);  // 四舍五入
        System.out.println(k);
        
        // 把BigDecimal转换成double
        double rs = k.doubleValue();
        System.out.println(rs);

    }
}

11. 传统时间

11.1 Date

系统当前的日期和时间

public class Test1Date {
    public static void main(String[] args) {
        // 创建一个Date的对象,代表当前系统时间信息
        Date d = new Date();
        System.out.println(d);

        // 拿到时间毫秒值
        long time = d.getTime();
        System.out.println(time);

        // 把时间毫秒值转化为日期对象
        time += 2 * 1000;
        Date d2 = new Date(time);
        System.out.println(d2);

        // 直接把日期对象的时间通过setTime方法进行修改
        Date d3 = new Date();
        d3.setTime(time);
        System.out.println(d3);
    }
}

11.2 SimpleDateFormat

把得到的时间格式化成用户喜欢的形式

public class Test2SimpleDateFormat {
    public static void main(String[] args) throws ParseException {
        // 1. 准备一些时间
        Date d = new Date();
        System.out.println(d);

        long time = d.getTime();
        System.out.println(time);

        // 2. 格式化日期对象——前端展示
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE a");
        String rs1 = sdf.format(d);
        String rs2 = sdf.format(time);
        System.out.println(rs1);
        System.out.println(rs2);

        // 3. 把字符串时间解析成日期对象——后端分析
        String dateStr = "2022-12-12 12:12:12";
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d2 = sdf2.parse(dateStr);  // 时间格式
        System.out.println(d2);
        long time2 = da.getTime();  // 时间毫秒值
    }
}

11.3 Calender

代表的是系统此刻时间对应的日历

可以单独获取、修改时间中的年、月、日、时、分、秒

Calendar时一个抽象类,但是提供了获取日历对象的方法

public class Test4Calendar {
    public static void main(String[] args) {
        // 1. 得到系统此刻时间对应的日历对象
        Calendar now = Calendar.getInstance();  // 返回的是Calendar子类的实例
        System.out.println(now);  // 月份是从0开始计算的,要想得到现在的月份,要+1

        // 2. 获取日历中的某个信息
        int year = now.get(Calendar.YEAR);
        System.out.println(year);

        // 3.拿到日历中记录的日期对象
        Date d = now.getTime();
        System.out.println(d);

        // 4. 拿到时间毫秒值
        long time = now.getTimeInMillis();
        System.out.println(time);

        // 5. 修改日历中的某个信息
        now.set(Calendar.DAY_OF_YEAR, 100);  // 修改月份为10月份
        System.out.println(now);
    }
}

问题:修改了之后其他参数没变,按道理应该会发生相应的变化????

12. JDK8新增的日期、时间

区别:

JDK8之前:

  • 设计不合理、使用不方便、很多被淘汰
  • 都是可变对象,修改后会丢失最开始的时间信息
  • 线程不安全
  • 只能精确到毫秒

JDK8之后:

  • 设计更合理、功能丰富、使用更方便
  • 都是不可变对象,修改后返回新的时间对象,不会丢失最开始的时间
  • 线程安全
  • 能精确到毫秒、纳秒

代替Calendar

12.1 LocalDate:年、月、日

12.2 LocalTime:时、分、秒

12.3 LocalDateTime:年、月、日 时、分、秒

  • public LocalDate toLocalDate()
  • public LocalTime toLocalTime()
  • public static LocalDateTime of(LocalDate date, LocalTime time)

类名 对象名 = 类名.now()——>得到对象

LocalDate

public class Test1_LocalDate {
    public static void main(String[] args) {
        LocalDate ld = LocalDate.now();
        System.out.println(ld);

        // 获取日期对象中的信息  get开头
        int year = ld.getYear();  // 年
        int mouth = ld.getMonthValue();  // 月1-12
        int day = ld.getDayOfMonth();  // 日
        int dayOfYear = ld.getDayOfYear(); // 一年中的第几天
        int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几

        // 修改某个信息  with开头
        LocalDate ld2 = LocalDate.now();
        ld2 = ld.withYear(2099);
        System.out.println(ld);  // 2023-12-12
        System.out.println(ld2);  // 2099-12-12

        // 把某个信息加多少 plus开头
        LocalDate ld3 = LocalDate.now();
        ld3 = ld2.plusMonths(1);

        // 把某个信息减多少 minus开头

        // 获取指定日期的LocalDate对象 public static LocalDate of(int year, int month, int dayOfMonth)
        LocalDate ld4 = LocalDate.of(2099, 12, 13);
        System.out.println(ld4);

        // 判断两个日期对象是否相等,在前还是在后:equals、isBefore、isAfter
        System.out.println(ld.equals(ld2));
    }
}

12.4 ZoneId:时区

ZoneId:代表时区ID

世界标准时间(UTC)

中国标准时间:UTC+8

类型:

洲名/城市名:Asia/Shanghai

国家名/城市名:Americal/New_York

ZoneId是一个抽象类,调用ZoneId.systemDefault();

12.5 ZonedDateTime:带时区的时间

import java.time.Clock;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Test4_ZoneId_ZoneIDDateTime {
    public static void main(String[] args) {
        // 获取系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId);
        System.out.println(zoneId.getId());

        // Java支持的全部时区ID——类方法
        System.out.println(ZoneId.getAvailableZoneIds());

        // 把某个时区ID封装成ZoneID对象
        ZoneId zoneId1 = ZoneId.of("America/New_York");

        // 获取带时区的时间
        ZonedDateTime now = ZonedDateTime.now(zoneId1);
        System.out.println(now);

        // 获得UTC
        ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
        System.out.println(now1);

        // 获得系统默认时区的时间
        ZonedDateTime now2 = ZonedDateTime.now();
        System.out.println(now2);

    }
}

代替Date

12.6 Instant:时间戳/时间线

代替SimpleDateFormat

可以精确到纳秒级。可以用来记录代码的执行时间,或者用于记录用户操作某个事件的时间点。

public class Test5_Instant {
    public static void main(String[] args) {
        // 创建
        Instant now = Instant.now();
        System.out.println(now);

        // 获取总秒数
        long second = now.getEpochSecond();
        System.out.println(second);

        // 获取不够1秒的纳秒数
        int nano = now.getNano();
        System.out.println(nano);
    }
}

12.7 DateTimeFormatter:用于时间的格式化和解析

其他补充SimpleDateFormat线程不安全

public class Test_DateTimeFormatter {
    public static void main(String[] args) {
        // 创建一个日期时间格式化器对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

        // 对时间进行格式化
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        String rs = formatter.format(now);
        System.out.println(rs);
    }
}

12.8 Duration:时间间隔(时、分、秒、纳秒)

public class Test {
    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(2025, 11, 11, 11, 10, 10);
        LocalDateTime end = LocalDateTime.of(2025, 11, 11, 11, 11, 11);

        // 得到Duration对象
        Duration duration = Duration.between(start,end);

        // 获取间隔信息
        System.out.println(duration.toDays());
        System.out.println(duration.toHours());
    }
}

12.9 Period:时间间隔(年、月、日)

倒计时相关的需求

计算两个LocalDate对象相差的年数、月数、天数

public class Test8_Duration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2029, 8, 10);
        LocalDate end = LocalDate.of(2029, 8, 15);

        // 创建Period对象,封装两个日期对象
        Period period = Period.between(start, end);

        // 获取时间差
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }
}

13. Arrays类

概念: 用来操作数组的工具类

public class ArraysTest1 {
    public static void main(String[] args) {
        // toString()返回数组的内容
        int[] arr = {10, 20, 30, 40, 50};
        System.out.println(Arrays.toString(arr));

        // copyOfRange(数组, 起始索引,结束索引)——包前不包后
        int[] arr1 = Arrays.copyOfRange(arr, 0, 3);
        System.out.println(Arrays.toString(arr1));

        // copyOf(数组, 新数组的长度),长度可以比新数组长,也可以比新数组短
        int[] arr2 = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(arr2));

        // 把数组中的元数据改为新数据又存进去setAll(double[] array, IntToDoubleFunction generator)
        double[] prices = {99.8, 128, 100};
        Arrays.setAll(prices, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                return prices[value] * 0.8;
            }
        });
        System.out.println(Arrays.toString(prices));


        // 对数组进行排序(默认是升序排序)
        Arrays.sort(prices);
        System.out.println(Arrays.toString(prices));

    }
}

如果数组中存储的是对象,应该如何进行排序?

在类中使用Comparable接口,重写compareTo()方法

public static void sort(T[] arr, Comparator<? duper T> c)

自定义排序规则时,需要遵循的官方约定:

  • 如果认为左边对象 大于 右边对象 应该返回正整数
  • 如果认为左边对象 小于 右边对象 应该返回负整数
  • 如果认为左边对象 等于 右边对象 应该返回0整数

14. 正则表达式

概念: 由一些特定的字符组成,代表的是一个规则——更简单,更便捷

作用:

  • 用来校验数据格式是否合法
  • 在一段文本中查找满足要求的内容
  • 用于搜索替换、分割内容

案例:

public class RegexTest1 {
    public static void main(String[] args) {
        // 需求:校验QQ号码是否正确,要求全部都是数字,长度是6-20之间,不能以0开头
        System.out.println(check(null));
        System.out.println(check("28256"));
        System.out.println(check("2825625257"));
        System.out.println(check("02825625257"));
        System.out.println(check("a2825625257"));

    }
    public static boolean check(String qq) {
        return qq != null && qq.matches("[1-9]\\d{5,19}");
    }
}

String匹配正则表达式的规则:

在这里插入图片描述

[内容]——只能用于匹配单个字符

.——可以匹配任意字符

在Java中,\由特殊用途,会把后面的一起当整体看,所以如果是\,转义回去

\\d

(?i)——忽略大小写:“abc”.matches(“(?i)abc”)

|——或

()——分组:括号内的内容出现一次或两次,可以加数量词

利用正则表达式查找内容:

  • 定义爬取规则,String类型
  • 把正则表达式封装成Pattern对象
  • 通过Pattern对象获取查找内容的匹配器对象
  • 用匹配器对象在数据中不断寻找
String regex = "(1[3-9]\ \d{9})|(\\w{2,}@\\w{2,20}(\ \.\\w{2,20}){1,2})"

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(data);

if (matcher.find()) {

	String s = matcher.group();

}


利用正则表达式替换、分割内容:

public class RegexTest2 {
    public static void main(String[] args) {
        // 去掉字符串中重复的字
        String s1 = "我我我喜喜喜喜欢编程程程程";
        System.out.println(s1.replaceAll("(.)\\1+", "$1"));  // 我喜欢编程
        System.out.println(s1);  // 我我我喜喜喜喜欢编程程程程

        String s2 = "古力娜扎aa888马儿扎哈bb222迪丽热巴";
        String[] s = s2.split("\\w+");
        System.out.println(Arrays.toString(s));

    }
}

15. 异常

异常就是代表程序出现的问题

异常的体系:

  1. 异常的祖宗类:Java.lang.Throwable
  2. 直接子类:
  • Error——系统级别的错误,面向的是sun公司,不是面向程序员的
  • Exception——异常,程序可能出现的问题,通常用Exception以及它的孩子来封装程序出现的问题

Exception分类:

  • 运行时异常: 运行时才会出现的异常
  • 编译时异常: 编译阶段就会出现错误提醒
public class ExceptionTest1 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try {
            Date d = sdf.parse("2020-11-22 10:12");
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
    }
}

自定义异常:

try——内部存放程序运行的代码

catch——可以输出信息,也可以进行修复操作

throws——不建议抛具体的异常,全部用Exception;运行时才抛出的异常不用throws

自己定义的异常类要继承RuntimeException

异常处理:

开发中处理方式:

  • 捕获异常,记录异常并响应合适的信息给用户
  • 捕获异常,尝试重新修复
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值