Java基础 Day14

包装类/包裹类(wrapper)

  • 在Java语言中,每一种基本数据类型都对应一个类类型,这些类称为包裹类。

请添加图片描述

  • 包裹类位于java.lang包中,是最常用类之一。

  • 包裹类的实例是以对象方式来表示对应基本类型的数据。

  • 包裹类中提供了大量常用的操作数据的方法

  • 用途:

    • 常被用于集合等一些需要使用类类型的场景
    • 在企业编程中,要求实体类(像Student这样用于封装数据的类)中的属性,都必须使用包裹类类型
    • 使用包裹类提供的一些静态方法
  • 注意:

    • 方法中的局部变量,还是使用基本数据类型
    • 涉及到运算的时候,还是优先使用基本数据类型
包裹类的示例
  • 可以将数据在基本类型和包裹对象之间进行转换

  • 以Integer类为例:

  int num = 420;
  
  // 创建num的对象(包裹类)类型
  Integer numObj= new Integer(num);      // 
  
  //取出包裹对象中的数值
  int num1 = numObj.intValue();          // 称为拆箱
  • 包裹类还提供了其他可用方法,例如将字符串转换为数字:
  String str =1234;
  int x = Integer.parseInt(str);
自动装箱与拆箱
  • 可以使用包裹类的自动装箱(基本类型->包裹对象)和自动拆箱(包裹对象-> 基本类型 )功能以简化编程

  • 例如:

  int num = 120;
  
  Integer numObj = num;       // 称为自动装箱
  
  int num1 = numObj;        // 称为自动拆箱
  • 自动装、拆箱是在编译时完成,过度使用会对性能带来负面影响。
  public class TestWrapper {
      public static void main(String[] args) {
          int num = 10;
          Integer num1 = new Integer(20);        //装箱
          int num2 = num1.intValue();	           //拆箱
  
          System.out.println("num1 = " + num1 + "  num2 = " + num2);
  
          Integer num3 = 30;     //自动装箱
          int num4 = num3;       //自动拆箱
          System.out.println("num3 = " + num3 + "  num4 = " + num4);
      }
  }
  1. 什么是包裹类?基本数据类型对应的类类型
  2. 包裹类有几种?8种
  3. 包裹类的作用?
    1. 使用对象来封装基本类型的数据
    2. 提供了常用的操作数据的方法,如parseInt()
  4. 包裹类用在哪?
    1. 需要使用对象的集合种
    2. 实体类的属性
    3. 使用其中的常用方法
  5. 包裹类对象是否可以直接参与运算?
    1. 语法上可以
    2. 实际是先执行自动拆箱,然后使用基本数据类型进行运算
不可变类
  • 所有的基本数据类型的包装类和String都属于不可变类,即:
    • 类使用final修饰,不可被继承
    • 类中实际保存数据的属性使用final修饰,其值一旦被赋予,不可改变

数学类

Math类
  • 位于java.lang包中,是一个包含了常用数学函数(均为静态方法)和常量的final类。

  • Math类中常用的数学函数及常量包括:

    • 截断函数:ceil(取高值)、floor(取低值) 和 round(四舍五入)
    • 变量函数:max(最大值)、min(最小值)
    • 随机函数:random(0.0≤n<1.0之间)
    • 常量:PI
  public class TestMath {
      public static void main(String[] args) {
          float f1 = 10.23f, f2 = 20.78f;
          System.out.println("    \t" + f1 + "    \t" + f2);
          System.out.println("ceil:\t" + ceil(f1) + "\t" + ceil(f2));
          System.out.println("floor:\t" + floor(f1) + "\t" + floor(f2));
          System.out.println("round:\t" + Math.round(f1) + "\t" + round(f2));
          System.out.println("max:\t" + max(f1, f2));
          System.out.println("min:\t" + min(f1, f2));
          System.out.println("产生10-20之间的随机整数:" 
                             + (int) (random() * 10 + 10));
      }
  }
BigDecimal类—提供小数的精确运算(以字符串形式传入)
//当参数以字符串形式传入时就可以进行精确运算
BigDecimalbd1=newBigDecimal("2.1");

BigDecimalbd2=newBigDecimal("1.9");

//通过调用方法让对象之间进行运算
System.out.println(bd1.subtract(bd2));
BigInteger类—提供超大数之间的运算
public class MathDemo3{

    public static void main(String[] args){
        //超大数之间的运算
        BigInteger bi1=new BigInteger("54738947583475874538753723482743828348294287648726478627846287647826487267846278647826478627634876768768767676786876876786876786786876786876786876876876876");

        BigInteger bi2=new BigInteger("346573488980989898908098998778678676876876876768687678678767867867862783676287536215712316726781627617261762616786178627816287126871269162716786192681768716287162716278617");
        //调用方法让超大数之间进行相乘
        System.out.println(bi1.multiply(bi2));
    }
}

面试题:如何实现2个32位长度的整型的乘法运算?

  1. 可以利用Java提供的BigInteger来实现,该类定义了超长整型运算的常规方法
  2. BigInteger内部基于int[]数组来保存长整数的每一位数字,然后计算算法实现它们的各类运算
  3. 原理…

日期时间类

1. Date类
  • JDK1.0就开始存在了,历史相当悠久,它的大部分构造器和方法已经过时了,不再推荐使用。
  • JDK8中未过期的2个构造器如下:
    • Date():生成一个代表当前日期的Date对象。该构造器在底层调用System.currentTimeMillis()获得long长整数作为日期参数。
    • Date(long date):根据指定的long型整数生成一个Date对象。该构造器的参数表示创建的Date对象和GMT1970年1月1日00:00:00之间的时间差,以毫秒为单位。
  • 时间戳(timestamp)
    • 描述当前时间和GMT1970年1月1日00:00:00之间的时间差,以毫秒为单位
  • JDK8中未过期的方法:
    • boolean after(Date when):测试该日期是否在指定的日期when之后。
    • boolean before(Date when):测试该日期是否在指定的日期when之前。
    • long getTime():返回该时间对应的long 型整数,即从GMT 1970-01-01 00:00:00到该Date对象之间的时间差,以毫秒为单位。
    • void setTime(long time):设置该Date对象的时间
2. SimpleDateFormat类—提供字符串和日期相互转换
  • 字符串转成日期(parse方法)

  • 日期转成字符串(format方法)

  //把字符串转成日期
  String str="2012-12-12 12:12:12";
  //创建对象
  //指定解析格式
  SimpleDateFormat sdf1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  //调用方法让字符串转成日期
  Date date=sdf1.parse(str);
  
  //把日期转成字符串
  //创建对象
  SimpleDateFormat sdf2=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
  
  //调用方法来让日期转成字符串
  String s=sdf2.format(date);
  System.out.println(s);
  • 注:simpleDateFormat是线程不安全的,不适用于多线程场景
3. Calendar
  • Calendar类本身是一个抽象类,它是所有日历类的模板,但不能之间创建对象,但它提供了几个静态getInstance()方法来获取Calendar对象

  • Calendar和Date都是日期的工具类,它们之间可以自由转换,如下代码所示:

  Calendar cal = Calendar.getInstance();
  //从Calendar对象中取出Date对象
  Date date = cal.getTime();
  //通过Date对象获取对应的Calendar对象
  Calendar cal2 = Calendar.getInstance();
  cal2.setTime(date);
  • Calendar提供了大量的访问、修改日期的方法,常用的如下:

    • void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
    • int get(int field):返回指定日历字段的值。
    • int getActualMaximum(int field):返回指定的日历字段可能拥有的最大值。例如月,最大值为11。
    • int getActualMinimum(int field):返回指定的日历字段可能拥有的最小值。例如月,最小值为0。
    • void roll(int field,int amount):与add方法类似,区别在于加上amount后如果超过了该字段的最大范围,也不会向上一个字段进位。
    • void set(int field,int value):将给定的日历字段设置为给定值。
    • void set(int year,int month,int date):设置Calendar对象的年、月、日3个字段的值。
    • void set(int year,int month,int date,int hour,int minute,int second):设置Calendar对象的年、月、日、时、分、秒6个字段的值。
  • 可以看出上面很多方法都需要一个int类型的field参数,field时Calendar类的类变量,如Calendar.YEAR、Calendar.MONTH、Calendar.DATE等分别代表了年、月、日、时、分、秒等字段,需要注意的是Calendar.MONTH月份的起始值是0,范围是0-11。

Java8新增的日期、时间包

为了弥补传统Java对日期、时间处理的不足,Java8提供了一套全新的日期时间库。Java8专门新增了一个java.time包,该包下包含了如下常用类:

  • Clock:该类用于获取指定时区的当前日期、时间。该类可以取代System类的currentTimeMillis()方法,该类提供了大量的方法获取当前的日期和时间
  //获取当前Clock
  Clock clock = Clock.systemUTC();
  //获取clock对应的毫秒数
  //等于System.currentTimeMillis()
  System.out.println(clock.millis());
  System.out.println(System.currentTimeMillis());
  • Duration:该类代表持续时间
  Duration d = Duration.ofSeconds(600);
  System.out.println("600秒="+d.toMinutes()+"分");
  System.out.println("600秒="+d.toHours()+"时");
  System.out.println("600秒="+d.toDays()+"天");
  • LocalDate:该类代表不带时区的日期,如:2019-02-24。该类主要提供了以下几个方法:

    1)now():获取当前日期。

    2)now(Clock clock):获取clock对应的日期。

    3)minusXxx():在当前年份基础上减去几年、几月、几周或几日等。

    4)plusXxx():在当前年份基础上加上几年、几月、几周或几日等。

  • LocalTime:该类代表不带时区的时间,如:10:20:09。该类主要提供了以下几个方法:

    1)now():获取当前时间。

    2)now(Clock clock):获取clock对应的时间。

    3)minusXxx():在当前年份基础上减去几小时、几分、几秒等。

    4)plusXxx():在当前年份基础上加上几小时、几分、几秒等。

  • LocalDateTime:该类代表不带时区的日期、时间,如:2019-02-24T10:20:09。该类主要提供了以下几个方法:

    1)now():获取当前日期、时间。

    2)now(Clock clock):获取clock对应的日期、时间。

    3)minusXxx():在当前年份基础上减去几年、几月、几周或几日、几小时、几分、几秒等。

    4)plusXxx():在当前年份基础上加上几年、几月、几周或几日、几小时、几分、几秒等。

日期时间的一些规约
  1. 【强制】日期格式化时,传入pattern中表示年份统一使用小写的y。 说明:日期格式化时,yyyy表示当天所在的年,而大写的YYYY代表是week in which year(JDK7之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的YYYY就是下一年。

    正例:表示日期和时间的格式如下所示: new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”)

  2. 【强制】在日期格式中分清楚大写的M和小写的m,大写的H和小写的h分别指代的意义。 说明:日期格式中的这两对字母表意如下: 1) 表示月份是大写的M; 2) 表示分钟则是小写的m; 3) 24小时制的是大写的H; 4) 12小时制的则是小写的h。

  3. 【强制】获取当前毫秒数:System.currentTimeMillis(); 而不是new Date().getTime()。 说明:如果想获取更加精确的纳秒级时间值,使用System.nanoTime的方式。在JDK8中,针对统计时间等场景,推荐使用Instant类。

  4. 【强制】不允许在程序任何地方中使用:

    1)java.sql.Date

    2)java.sql.Time

    3)java.sql.Timestamp。

    说明:第1个不记录时间,getHours()抛出异常;第2个不记录日期,getYear()抛出异常;第3个在构造方法super((time/1000)*1000),fastTime和nanos分开存储秒和纳秒信息。
    反例: java.util.Date.after(Date)进行时间比较时,当入参是java.sql.Timestamp时,会触发JDK BUG(JDK9已修复),可能导致比较时的意外结果。

  5. 【强制】不要在程序中写死一年为365天,避免在公历闰年时出现日期转换错误或程序逻辑错误。

正例:
	// 获取今年的天数 
    int daysOfThisYear = LocalDate.now().lengthOfYear(); 
	// 获取指定某年的天数 
	LocalDate.of(2011, 1, 1).lengthOfYear();
反例: 
    // 第一种情况:在闰年366天时,出现数组越界异常 
    int[] dayArray = new int[365]; 
	// 第二种情况:一年有效期的会员制,今年1月26日注册,硬编码365返回的却是1月25日 
	Calendar calendar = Calendar.getInstance(); calendar.set(2020, 1, 26); 	
	calendar.add(Calendar.DATE, 365);
  1. 【推荐】避免公历闰年2月问题。闰年的2月份有29天,一年后的那一天不可能是2月29日。

  2. 【推荐】使用枚举值来指代月份。如果使用数字,注意Date,Calendar等日期相关类的月份month取值在0-11之间。 说明:参考JDK原生注释,Month value is 0-based. e.g., 0 for January.

    正例: Calendar.JANUARY,Calendar.FEBRUARY,Calendar.MARCH等来指代相

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值