常用类(BigInteger和BigDecimal、日期类)+练习

8、BigInteger和BigDecimal类

应用场景:

  1. BigInteger 适合保存比较大的整形
  2. BigDecimal 适合保存精度更高的浮点型(小数)

8.1 BigInteger和BigDecimal的常用方法

BigInteger:

当我们编程中,需要处理很大的整数,long就不够用了,就可以用BigInteger

  • add 加

    1. 在对BigInteger 进行加减乘除时,需要使用对应的方法,不能直接进行加减乘除
    2. 可以创建一个要操作的 BigInteger 然后进行相应的操作
    BigInteger bigInteger = new BigInteger("54641132165416484");
    BigInteger bigInteger2 = new BigInteger("546");
    BigInteger add = bigInteger.add(bigInteger2)
    
  • subtract 减

  • multiply 乘

  • divide 除

BigDecimal:

当我们需要保存一个精度很高的数时,double 不够用

  • add 加

    BigInteger bigInteger = new BigInteger("54641132165416484");
    BigInteger bigInteger2 = new BigInteger("546");
    BigInteger add = bigInteger.add(bigInteger2)
    
  • subtract 减

  • multiply 乘

  • divide 除

    1. 可能抛出异常 ArithmeticException
    2. 可以在调用devide方法时,指定精度:BigDecimal.ROUND_CEILING,如果有无限循环小数,就会保留 分子(除数) 的精度
    System.out.println(bigDecimal.devide(bigDecimal2,BigDecimal.ROUND_CEILING));
    

9、Date、Calendar、LocalDate...

9.1 第一代日期类

  1. Date:精确到毫秒,代表特定的瞬间

    • 这里的 Date 类是在 java.util 包
    • 默认输入的日期格式是国外的方式,因此通常需要对格式进行转换
    Date d1= new Date0;//获取当前系统时间
    Date d2=new Date(9234567);//通过指定毫秒数得到时间
    System.out.println(d1.getTime()); 
    System.out.println(d2); 
    
  2. SimpleDateFormat:格式和解析日期的类

    • 格式化和解析日期的具体类。它允许进行格式化(日期 --> 文本)、解析(文本 --> 日期)和规范化
    • 创建 SimpleDateFormat 对象,可以指定相应的格式,这里的格式使用的字母不能乱写
    • 可以把一个格式化的String转成对应的 Date ,得到Date仍然在输出时,还是依照国外的形式,如果希望指定格式输出,需要转换
    • 在把 String ->Date,使用的 sdf 格式需要和你给的 String 的格式一样,否则会抛出转换异常
    //日期 --> 文本
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
    String format = sdf.format(d1);// format:将日期转换成指定格式的字符串
    
    //文本 --> 日期
    String s = "1996年01月01日 10:20:30 星期一";
    Date parse = sdf.parse(s);
    

9.2 第二代日期类

第二代日期类,主要是 Calendar 类

Calendar:

public abstract class Calendar extends Object implements Serializable,Cloneable, Comparable<Calendar>
  1. Calendar 类是一个抽象类,并且构造器是私有的 private
  2. 可以通过 getInstance() 来获取实例
  3. 它为特定瞬间量一组诸如 YEAR、MONTH、DAY OF MONTH、 HOUR 等日历字段之间的转换提供了一些方法,并为操作日历方法(例如获取下星期的日期)提供了一些方法
  4. Calendar 没有提供对应的格式化类,因此需要程序员自己组合来输出
  5. 如果我们需要按照 24 小时进制来获取获取时间
    • Calendar.HOUR改成>Calendar.HOUR_OF_Day

应用实例

Calendar c = Calendar.getlnstance(); //创建日历类对象,比较简单,自由
System.out.println(c);//全部信息太长,希望获取某个字段


//获取日历对象的某个日历字段
System.out.println("年:" + c.get(Calendar.YEAR));
System.out.println("月:" + (c.get(Calendar.MONTH) + 1));//为什么要 + 1 ? 因为Calendar返回月时,是按 0 开始编号
System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH));
System.out.println("小时:" + c.get(Calendar.HOUR));
System.out.println("分钟:" + c.get(Calendar.MINUTE));
System.out.println("秒:" + c.get(Calendar.SECOND));

//Calender 没有专门的格式化方法,所以需要程序员自己来组合显示
System.out.println(c.get(Calendar.YEAR) + "年" + (c.get(Calendar.MONTH) + 1) + "月" + c.get(Calendar.DAY_OF_MONTH) + "日");

9.3 第三代日期类

前面两代日期类的不足分析

**JDK 1.0 **中包含了一个java.util.Date类,但是它的大多数方法已经在 JDK 1.1引入
Calendar类之后被弃用了。而Calendar也存在问题是:

  1. 可变性:像日期和时间这样的类应该是不可变的
  2. 偏移性:Date中的年份是从1900开始的,而月份都从0开始
  3. 格式化:格式化只对Date有用,Calendar则不行
  4. 此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)

第三代日期类常用方法:JDK8加入

(1):

LocalDate(日期 / 年月日)、LocalTime(时间 / 时分秒)、LocalDateTime(日期时间)

  • LocalDate只包含日期,可以获取日期宇段
  • LocalTime只包含时间,可以获取时间字段案例演示
  • LocalDateTime包含日期+时间,可以获取日期和时间字段

解读:

  1. 使用new(),返回表示当前日期时间的对象
LocalDateTime ldt = LocalDateTime.now(); //或是LocalDate.now();  //LocalTime.now();
System.out.printin(ldt);

System.out.printin(ldt.getYear());
System.out.printin(ldt.getMonth()); //返回月份的英文
System.out.printin(ldt.getMonthValue()); //返回月份的数字
......

(2):

DateTimeFormatter格式日期类

  • 类似于SimpleDateFormat,使用 DateTimeFormatter 对 LocalDateTime 进行格式化

案例演示:

  1. 创建 DateTimeFormatter 对象
LocalDateTime ldt = LocalDateTime.now();

//关于DateTimeFormatter 的各个格式参数,需要看jdk8的文档.

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分钟ss秒");
String strDate = dateTimeFormatter.format(ldt); 

(3):

Instant 时间戳

  • 类似于Date,提供了一系列和Date类转换的方式

Instant->Date:

Date date = Date.from(instant);

Date>Instant:

Instant instant =date.tolnstant();

//通过静态方法 now() 获取表示当前时间戳的对象
Instant now = Instant.now();
System.out.println(now);

//通过 from 可以把 Instant 转成Date
Date date = Date.from(now);

//通过 date 的toInstant() 方法,可以把 date 转成 Instant对象
Instant instant = date.tolnstant();

(4):

第三代日期类更多方法

  • LocalDateTime类

  • MonthDay类:检查重复事作

  • 是否是闰年

  • 增加日期的某个部分

  • 使用plus方法测试增加时间的某个部分

    LocalDateTime ldt = LocalDateTime.now();
    LocalDateTime localDateTime = ldt.plusDays(999);
    
  • 使用minus方法测试查看一年前和一年后的日期

    LocalDateTime ldt = LocalDateTime.now();
    LocalDateTime localDateTime = ldt.minusDays(999);
    

10、练习

一、String翻转

(1)将字符串中指定部分进行反转。比如将”abedef"反转为"aedcbf"
(2)编写方法 public static String reverse(String str, int start, int end) 搞定

思路分析:

  1. 先把方法定义确定

  2. 把 String 转成 char[] ,因为 char[] 的元素是可以交换的

  3. 画出分析示意图

    ![常用类 10.1](D:\桌面\博客\picture\常用类 10.1.png)

  4. 代码实现

public static String reverse(String str, int start, int end){
    //对输入的参数做一个验证
    //重要的编程技巧:写出正确的情况,然后取反即可
    if(!(str != null && start >= 0 && end > start && end < str.length())){
        throw new RuntimeException("参数不正确");
    }

    
    char[] chars = str.toCharArray();
	char temp=''; //交换辅助变量
	for (int i = start, j= end; i < j; i++, j--){
        temp = chars[i];
		chars[i]= chars[j];
		chars[j]= temp;
    }
	//使用chars 重新构建一个String 返回即可
	return new String(chars);
}

二、注册处理

输入用户名、密码、邮箱,如果信息录入正确,则提示注册成功,否则生成异常对象

要求:

(1)用户名长度为2或3或4

(2)密码的长度为6,要求全是数字

(3)邮箱中包含@和. 并且@在.的前面 isDigital

思路分析:

  1. 先编写方法 userRegister( String name , String pwd , String email ){}
  2. 针对输入的内容进行校核,如果发现有问题,就抛出异常,给出提示
  3. 单独的写一个方法,判断 密码是否全部是数字
public static void userRegister( String name , String pwd , String email ){
    //过关
    //第一关
    int userLength = name.length();
	if(!(userLength >= 2 && userLength <= 4)){
        throw new RuntimeException("用户名长度为2或3或4");
    }

	//第二关
	if(pwd.length() == 6 && isDigital(pwd)){
        throw new RuntimeException("密码的长度为6,要求全是数字");
    }
    
    //第三关
    int i = email.indexOf('@');
	int j = email.indexOf('.');
    if(!(i > 0 && j > i)){
        throw new RuntimeException("邮箱中包含@和.,并且@在.的前面");
    }

}
public static boolean isDigital(String str){
    char[] chars = str.tocharArray();
    for(int i=0; i< chars.length; i++) {
        if(chars[i] <'0' || chars[i] >'9'){
             return false;
        }
    } 
    return true;
}

三、

(1)编写java程序,输入形式为:Han Shun Ping的人名,以Ping,Han .S的形式打印出来,其中.S是中间单词的首字母。
(2)例如输入"Willian Jefferson Clinton”,输出形式为:Clinton, Willian. J

思路分析:

  1. 对输出的字符串进行 分割 split(" ")(比索引空格快)
  2. 对得到的String[] 进行格式化 Strinhg.format()
  3. 对输入的字符串进行校验
public void printName(String str){
    if(str == null){
        System.out.println("str 不能为空");
		return;
    }
    
    String[] names = str.split(" ");
	if(names.length != 3){
        System.out.println("输入的字符串格式不对");
		return;
    }

    String format = String.format("%s, %s .%c", names[2], names[0], names[1].toUpperCase().charAt(0));
    System.out.println(format);
}

四、字符串统计

输入一个字符串,判断里面有多少个大写字母,多少个小写字母,多少个数字

思路分析:

  1. 遍历字符串,如果 char 在‘@'~'9',就是一个数字
  2. 如果 char 在'a'~'z’,就是一个小写字母
  3. 如果 char 在'A'~'Z',就是一个大写字母
  4. 使用三个变量来记录数据
public static void countStr(String str){
    if (str == null) {
        System.out.println("输入不能为 null");
		return;
    }
	

	int strLen = str.length();
	int numCount = 0;
	int LowerCount = 0;
	int upperCount = 0;
    int otherCount = 0;
	for (int i = 0; i< strLen; i++){
		if(str.charAt(i) >='0' && str.charAt(i) <= '9'){
            numCount++;		
		} else if(str.charAt(i) >= 'a' && str.charAt(1)<='2'){
            lowerCount++;
        } else if(str.charAt(1) >= 'A' && str.charAt(i) <=·Z'){
            upperCount++;
		}else {
			otherCount++;
   		}
     }
                  
     System.out.println(...);  
     ... //输出
}

五、String类的内存布局

试着写出运行结果

已知Animal类有属性name,可以通过有参构造为属性赋值

class Animal {
	String name;
	public Animal(String name){
		this.name= name;
    }
}
String s1="hspedu";
Animal a = new Animal(s1);
Animal b = new Animal(s1);
System.out.println(a==b);   //false
System.out.println(a.equals(b));   //false,调用animal的equals,但equals没有重写
System.out.println(a.name == b.name);   //true

String s4 = new String("hspedu");
String s5 = "hspedu";

System.out.println(s1 == s4);   //false
System.out.println(s4 == s5);   //false

String t1 = "hello" + s1;
String t2 = "hellohspedu";
System.out.printin(t1.intern() == t2);   //true

![常用类 10.2](D:\桌面\博客\picture\常用类 10.2.png)

posted @ 2025-08-23 21:46  lu璐  阅读(16)  评论(0)    收藏  举报