第十五次作业

目录

1.什么是包装类:

【2】对应关系:

【3】已经有基本数据类型了,为什么要封装为包装类?

【4】是不是有了包装类以后就不用基本数据类型了?

2.日期相关类 

2. sql.Date

 3. SimpleDateFormat

4. Calendar 

 5. jdk1.8新增第三批API LocalDate、LocalTime、LocalDateTime

 6. DateTimeFormatter 自定义格式

3.Math类

 1. API文档中学习

 2. 走一遍代码

4.Random类 

5. String类

 1. String类的本质

2.String的常用方法 

3. String内存分析

4.StringBuilder类 

5. 解释可变和不可变 

6. StringBuffer概述

7. String,StringBuilder,StringBuffer的区别与联系


 

1.什么是包装类:

以前定义变量,经常使用基本数据类型,

对于基本数据类型来说,它就是一个数,加点属性,加点方法,加点构造器,

将基本数据类型对应进行了一个封装,产生了一个新的类,---包装类。

int,byte.....>引用数据类型

包装类---->引用数据类型

【2】对应关系:

基本数据类型 对应的包装类 继承关系

【3】已经有基本数据类型了,为什么要封装为包装类?

1.java语言是面向对象的语言,最擅长操作各种各样的类。

2.以前学习装数据的数组,int[] String[] double[] Student[]

以后学习的装数据的集合,有一个特点,只能装引用数据类型的数据

【4】是不是有了包装类以后就不用基本数据类型了?

不是。

  • Integer类

【1】直接使用,无需导包:

java.lang

类 Integer

【2】类的继承关系:

java.lang.Object

-java.lang.Number

-java.lang.Integer

【3】实现接口:

所有已实现到的接口:

Selializable,Comparable<Integer>

 【4】这个类被final修饰,那么这个类不能有子类,不能继承:

public final class Integer

extends Number

implements Comparable<Integer>

【5】包装类是对基本数据类型的封装:对int类型封装产生了Integer

Integer类在对象中包装了一个基本类型int 的值。Integer类型的对象包含一个int类型的字段。

【6】类的历史:

从一下版本开始:

JDK1.0

【7】属性:

 

public class test01 {//创建类
 
	public static void main(String[] args) {//主方法
	System.out.println(Integer.MAX_VALUE);//输出最大值
	System.out.println(Integer.MIN_VALUE);//输出最小值
	//物极必反原理:
	System.out.println(Integer.MAX_VALUE+1);//输出
	System.out.println(Integer.MIN_VALUE-1);//输出
	}
 
}

【8】 构造器(发现没有空参构造器)

1.int类型作为构造器的参数:

Integer i1=new Integer(i2);

public class test02 {//创建类
 
	public static void main(String[] args) {//主方法
		Integer i1=new Integer(12);//构造器
		System.out.println(i1.toString());//输出信息
	Integer i2=	new Integer("12");//构造器
	System.out.println(i2);//输出
	
	}
 
}

 

【9】包装类特有的机制:自动装箱 自动拆箱:

public class Test03 {//创建类
 
	public static void main(String[] args) {//主方法
		//自动装箱:int--->Integer
		Integer i=12;//定义一个Integer对象并赋值
		System.out.println(i);//输出
		//自动拆箱:Integer --->int 
		Integer i2=new Integer(12);//创建构造器并传入值
		int num=i2;//定义一个int类型的变量并赋值
		System.out.println(num);//输出
 
	}
 
}

 

1.自动装箱 自动拆箱是从JDK1.5以后新出的特性

2.自动装箱 自动拆箱:将基本数据类型和包装类进行快速的类型转换。 

  1. 从属与java.lang包(属于这个包意味着直接使用,不用导入包)【图】
  2. 类的继承关系
  3. java.lang.Object
  4. ​ java.lang.Number
  5. ​ java.lang.Integer
  6. 实现接口 
  7. 被final修饰,那么这个类不能有子类,不能被继承
  8. 包装类是对基本数据类型的封装:对int类型封装产生了Integer。
  9. 类的历史
  10. 字段摘要 Field Summar

 

Integer i1 = new Integer(39);//Integer方法构造
Integer i2 = new Integer("abc");//报错,点进构造方法,发现是NumberFormatException
System.out.println(i2);

 

1.包装类特有机制,拆箱装箱(底层使用了方法完成,velueOf() 和 intValue() )可以自行断点查看

//自动装箱,int直接变成Integer
Integer i = 3;
//自动拆箱,Interger直接变成int相加
System.out.println(i+1);

2. 常用方法,主要查看JavaAPI文档自学,下面列举主要几个方法,可以在idea点进方法查看底层

  • comperTo() 在数字上比较两个Integer对象。 
Integer i = 2;
Integer i1 = 3;
Integer i2 = 3;
System.out.println(i.compareTo(i1));//-1
System.out.println(i1.compareTo(i));//1
System.out.println(i1.compareTo(i2));//0
  • equals()将对象和指定对象进行比较 
Integer i3 = new Integer(13);//通过new创建
Integer i4 = new Integer(13);
System.out.println(i3.equals(i4));//ture,equals被重写
System.out.println(i3 == i4);//false
 
Integer i5 = 1;//通过自动装箱创建
Integer i6 = 2;
System.out.println(6.equals(i5));//ture,equals被重写
System.out.println(i6 == i5);//ture,当自动装箱的值在-128~127之间自动装箱返回的是数,否则是地址

 

  • intValue()以 int 类型返回该Integer的值

  • parseInt()将字符串转成 int 类型

  • toString()返回一个表示该Integer的字符串

2.日期相关类 

Date d = new Date();
System.out.println(d);
System.out.println(d.toGMTString());//有横线花掉的是过失、过期、废弃方法
System.out.println(d.toLocaleString());

 

System.out.println(d.getTime());
System.out.println(System.currentTimeMillis());//效果一样,但是用第二个,因为是静态方法,快!第一个因为要创建对象,所以不够第二个效率高
//currentTimeMillis()是本地方法,没有方法体,因为方法体的实现不是通过Java写的
//这俩方法的作用,测试算法速度

2. sql.Date

Date d = new Date(1592055964263L);
System.out.println(d);
/*
1. 区别
    java.util.Date:年月日 时分秒
    java.sql.Date:年月日
2. 联系
    sql.Date 继承自 util.Date
3. 转换
 */
//util-->sql
java.util.Date d1 = new Date(1592055964263L);
Date d11 = (Date) d1;//方式一,强制转换 util-->sql
Date d12 = new Date(d1.getTime());//借助构造器
//sql-->util
d1 = d;//父类指向子类
//String --> sql.Date
Date d13 = Date.valueOf("2017-7-3");

 3. SimpleDateFormat

从前台过来的日期数据一般都是有格式的String,需要转换成util.Date类型 

  • String-->sql.Date

  • sql.Date-->util.Date

  • 局限性:日期必须是规定格式!

  • 引入新类DateFormat

java.sql.Date sdate = java.sql.Date.valueOf("2017-7-7");//String-->sql.Date,字符转只能是YYYY-MM-DD格式
Date ud = sdate;//sql.Date-->util.Date
//局限性:日期必须是规定格式!
 
 
//日期转换
//public class SimpleDateFormat(子类) extends DateFormat(父类)
DateFormat df = new SimpleDateFormat("yyyy MM dd");//转化标准已经定好(对标前台)
//String ---> Date
try {//需要try/catch才能使用
    Date d = df.parse("2017 03 07");//parse,根据给定字符串和格式生成日期
    System.out.println(d.toLocaleString());
} catch (ParseException e) {
    e.printStackTrace();
}
 
 
//Date ---> String
String format = df.format(new Date());//根据日期给出格式
System.out.println(format);

4. Calendar 

  • Calendar是一个抽象类,不能直接创建对象,使用子类实现
  • 可以使用静态方法Calendar.getInstance()创建。
  • 常用方法:get(),set()
  • 如何从String转换为Calendar
  • 练习:给出一个日期,打印出那一月正确的日历,且在给定日期标星号,如下图。

 

 

package com.xiaowei9s.commonuse.dateclass;
 
import java.sql.Date;
import java.util.Calendar;
import java.util.Scanner;
 
public class Demo05 {
    public static void main(String[] args) {
 
        //获取日期
        System.out.println("请输入日期(格式为YYYY-MM-DD):");
        Scanner sc = new Scanner(System.in);
        String strDate = sc.next();
        Date date = Date.valueOf(strDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
 
        //打印信息
        int nowday = cal.get(Calendar.DAY_OF_MONTH);
        System.out.println("日\t一\t二\t三\t四\t五\t六");
        for (int i = 0; i < cal.get(Calendar.DAY_OF_MONTH); i++) {//对齐一号是星期几
            System.out.print("\t");
        }
 
        for (int i = 1; i <= cal.getActualMaximum(Calendar.DATE); i++) {//遍历该月
            String day = i+"";
            if(i<=9){               //为了对齐一位数两位数
                day = i+" ";
            }
            if (i==nowday){ //在指定日期打星号
                day = i+"";
                System.out.print(day+"*"+"\t");
                continue;
            }
            cal.set(Calendar.DATE,i);
            if (cal.get(Calendar.DAY_OF_WEEK)==7){  //在换行时换行
                System.out.println(day+"\t");
                continue;
            }
            System.out.print(day+"\t");             //正常日期
        }
 
    }
}

 5. jdk1.8新增第三批API LocalDate、LocalTime、LocalDateTime

缺陷:

  • 可变性和不可变性不合理(不应该有set方法,不应该可以改日历,一个日历对象仅仅永远只能是一个时间,不可变)
  • 偏移性:getYear(),是从1900开始的,有偏移性
  • 格式化,格式化只能对Date格式化,而不能对Calendar格式化
  • 基于这些缺陷,创造了第三批Api。但是前面两批都有人用

1) LocalDate

2) LocalTime

3) LocalDateTime (最常用)

  • get方法
  • with方法(不可变体现)
  • 加减方法
  • toString() (无偏移性体现)

4) Demo
 

package com.xiaowei9s.commonuse.dateclass;
 
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalField;
 
public class Demo06 {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.now();//LocalDate获取当前日期
        LocalTime localTime = LocalTime.now();//LocalTime获取当前时间
        LocalDateTime localDateTime = LocalDateTime.now();//LocalDateTime获取当前时间日期
        System.out.println(localDateTime);
        System.out.println(localTime);
        System.out.println(localDate);
        LocalTime localTime1 = LocalTime.of(13,14);//获取指定时间
        LocalDate localDate1 = LocalDate.of(1999,9,3);//获取指定日期
        LocalDateTime localDateTime1 = LocalDateTime.of(2021,9,3,15,13,22,33);//获取指定时间日期
        System.out.println(localDateTime1);
        System.out.println(localDate1);
        System.out.println(localTime1);
 
 
        //下面只讲LocalDateTime
        //get方法
        System.out.println(localDateTime1.get(ChronoField.MONTH_OF_YEAR));
        System.out.println(localDateTime1.getYear());
        System.out.println(localDateTime1.getMonth());
        System.out.println(localDateTime1.getMonthValue());
        System.out.println(localDateTime1.getDayOfMonth());
        System.out.println(localDateTime1.getDayOfWeek());
        System.out.println(localDateTime1.getDayOfYear());
        System.out.println(localDateTime1.getHour());
        System.out.println(localDateTime1.getMinute());
        System.out.println(localDateTime1.getSecond());
        //with,不是set
        LocalDateTime localDateTime2 = localDateTime1.withHour(3);//不可变性,即使把时间变成三点,也不会将本来的时间替换,而是新给出除了时间变成3点的一个对象
        System.out.println(localDateTime1);
        System.out.println(localDateTime2);
        //加减操作
        LocalDateTime localDateTime3 = localDateTime1.plusDays(3);
        LocalDateTime localDateTime4 = localDateTime1.minusHours(5);
        System.out.println(localDateTime1);
        System.out.println(localDateTime3);
        System.out.println(localDateTime4);
 
    }
}

 

 6. DateTimeFormatter 自定义格式

用于转换LocalDateTime等与String转换的定义和规范.

方式一:

 

//方式一:预定义的标准格式
DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;//df可以帮助转换String和LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
String str = df1.format(localDateTime);
System.out.println(str);
 
TemporalAccessor parse = df1.parse("2021-09-04T11:25:23.5");
System.out.println(parse);

 方式二:

//方式二:本地相关的格式
//FormatStyle.FULL
//FormatStyle.LONG
//FormatStyle.MEDIUM
//FormatStyle.SHORT
DateTimeFormatter df2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);//df可以帮助转换String和LocalDateTime
String str1 = df2.format(localDateTime);
System.out.println(str1);
 
TemporalAccessor parse1 = df2.parse("2021-9-4 11:41:50");//格式不对会有异常
System.out.println(parse1);

方式三:

//方式三:自定义格式
DateTimeFormatter df3 = DateTimeFormatter.ofPattern("yyyy MM dd");//df可以帮助转换String和LocalDateTime
String str2 = df3.format(localDateTime);
System.out.println(str2);
TemporalAccessor parse2 = df3.parse("2021 09 04");
System.out.println(parse2);

3.Math类

 1. API文档中学习

 

  • 基本概述

  • 字段概述:

 

 

  • 构造器私有化(不想让任何人实例化出对象)
  • Math内部所有的属性和方法都是static,都是静态的,可以通过类名直接调用。

 2. 走一遍代码

  • 常用属性
System.out.println(Math.PI);System.out.println(Math.E);
  • 常用方法
System.out.println("随机数:"+Math.random());
System.out.println("绝对值:"+Math.abs(-5.6));
System.out.println("进一:"+Math.ceil(9.1));
System.out.println("舍一:"+Math.floor(9.9));
System.out.println("四舍五入:"+Math.round(9.9));
System.out.println("取最大:"+Math.max(3,9));
System.out.println("取最小:"+Math.min(9,28));
  • ps:如果静态引入了Math,而在本类中有同名方法,则会走本类的方法

4.Random类 

1. 自行在API文档中初步了解Random类

2. 不管是无参数构造Random,还是Math类的random方法,最后底层都是到Random类的有参构造中。

3. Demo

package com.xiaowei9s.commonuse.mathclass;import java.util.Random;public class Demo02 {
	public static void main(String[] args) {
		System.out.println("Math随机数:"+Math.random());//math中生成随机数:底层还是用了Random类        
		//Random类学习        
		//带参数构造的Random        
		Random random = new Random(1858858L);//只要种子固定,则每次启动都会是同一个随机数开始,只有next后才是不同的随机数,并且几次都是一样        
		//解决办法:给出每次都不一样的种子        
		Random random1 = new Random(System.currentTimeMillis());        
		System.out.println(random.nextInt());        
		System.out.println(random1.nextInt());        //空参数构造的Random:表面无参,实际底层还是调用带参        
		Random random2 = new Random();        
		System.out.println(random2.nextInt(10));        
		System.out.println(random2.nextDouble());       
		System.out.println(random2.nextFloat());    
	}
}

 

5. String类

 1. String类的本质

  • 将字符串起来,就是字符串,是不可变类
  • 所有的字符串都是一个实例化出来的对象,例如"abc","你好世界","helloworld"等。
  • 字符串内容不可变,类比LocalDateTime类的不可变性
  • String底层是一个char类型的数组

 

2.String的常用方法 

  • String()空参构造器,给出一个空的value。
  • String(String original),将original的value和hash给到正构造的String对象。
  • String(char value[]),将value数组中的值复制到正构造的String对象的属性value中。
  • length(),字符串底层数组长度。
  • isEmpty(),字符串底层数组是否为空。
  • charAt(int index),字符串中底层数组相对应下标的对应值。
  • equals(Object object),比较两个字符串是否值相等,已被重写。
     

 

  • compareTo(String anotherString),对比两个字符串,实现了一个Comparable接口,需要重写compareTo方法,已被重写。 

 

 

  •  剩下的看Demo
package com.xiaowei9s.commonuse.stringclass;
 
import java.util.Locale;
 
public class Demo01 {
    public static void main(String[] args) {
        //通过空参构造器创建对象
        String str = new String();
        String str1 = new String("this string");
        String str2 = new String(new char[]{'3','4','5'});
 
        String str3 = "xiaowei";
        System.out.println("str3字符串长度:"+str3.length());
        System.out.println("str字符串是否为空:"+str.isEmpty());
        System.out.println("str3字符串下标3的对应字符:"+str3.charAt(3));
        String s = str3;
        System.out.println("str3是否和str2相等:"+str3.equals(str2));//已被重写,不是比较地址而是值
 
        String str4 = "aaab";
        String str5 = "bbbababc";
        System.out.println("str4和str5对比比较:"+str4.compareTo(str5));
 
        String str6 = "123456789";
        System.out.println(str6.substring(3));//456789,123没了,截除前三
        System.out.println(str6.substring(3, 6));//456,123 789没了,截除前三,截除6后
        System.out.println(str6.concat("777"));//拼接字符串
        System.out.println(str6.replace('8','*'));//将第一个字符全部用第二个代替
        for (String s1:"1-2-3-4-5-6-7-8-9".split("-")
             ) {
            System.out.println(s1);
        }//看到字符即分割
        System.out.println(str4.toUpperCase(Locale.ROOT));//转大写
        System.out.println(str4.toUpperCase(Locale.ROOT).toLowerCase(Locale.ROOT));//转小写
        String str7 = "   ada a s 123  ";
        System.out.println(str7.trim());//去除首尾空格
        System.out.println(String.valueOf(2));
        System.out.println(String.valueOf('a'));
        System.out.println(String.valueOf(3.1415926535));
        System.out.println(String.valueOf(true));//将其他类型转换成String类型
    }
}

3. String内存分析

String在常量池中放置了一个变量,如果后续有结果相同的变量那就不会在增加一个变量,比如String s = "abc";后续如果再来了一个String s1 = "ab"+"c",常量池中也只会有一个"abc",不会有两个。但是注意使用String(String original)构造的String对象则不同。
 

String s = "1"+"23";String s1 = "12"+"3";String s2 = "1"+"2"+"3";String s3 = "123";String s4 = "123"+"";System.out.println(s4 == s1);//trueSystem.out.println(s2 == s3);//true

 上面的字符串会进行编译优化,合并成完整的字符串,可使用反编译工具查看class文件如下:

 

 

 

 ​ 使用new 创建String:

String s6 = new String("123");System.out.println(s6 == s4);//false

 

  •  拼接字符串分析:
String s = "abc";
String b = s + "def";
System.out.println(b);

 反汇编,借助反汇编来分析整个底层做的事情:

 

 进行反汇编命令后得到反汇编代码,我们观察:

 

 在观察中知道用了两次append,所以在使用变量a和"def"进行拼接的时候,不会进行编译优化,不会直接变成"abcdef",而是会使用StringBuilder类中的方法进行追加。

4.StringBuilder类 

可变字符串类有:StringBuilder类,StringBuffer类

不可变字符串类:String类

疑问:

  1. 可变和不可变啥意思啊?
  2. 本笔记重点:StringBuilder类。
  3. StringBuilder和StringBuffer类。
  • 在API文档中查看基本概述,和基本方法,和String区别不大
  • 查看父类AbstractStringBuilder
  • 有两个属性,和String底层差不多,也有char value[]数组,有int count属性,用于数组中被使用的长度。
  • 分析构造器与append()
     

 

StringBuilder sb = new StringBuilder();//表面是空的构造器,底层对value数组初始化长度为16
StringBuilder sb1 = new StringBuilder(3);//底层对value数组初始化长度为3
StringBuilder sb2 = new StringBuilder("abc");//底层对value数组初始化长度为3
sb2.append("aaa").append("bbbbbb").append("ccccccccc").append("ddddddddddddd");//链式调用  return this

 

构造器中的StringBuilder(String str)底层调用的是append的方法,我们着重分析append方法。

在使用StringBuilder(String str)时,首先会根据str的长度,在后面加上16,以这个长度构成StringBuilder的value长度,比如str="abc",则StringBuilder的value长度就会使3+16=19 。

在一个StringBuilder的对象中使用append(String str)的时候,父类抽象类AbstractStringBuilder类的底层代码会观察你追加的长度是否已经超过当前StringBuilder对象的value长度。

如果长度没有超过,则直接将str中的char value[]中的值 从开头 复制到 StringBuilder对象中的char value[]最后一个字符后。

如果长度超过了,则会先对StringBuilder中的char value[]进行扩容至充足,过程:创建一个新的足够长度的char value[],并且将原有(还没有追加的)字符串复制到新的char value[]中,然后就将str中的char value[]中的值 从开头 复制到 StringBuilder对象中的char value[]最后一个字符后。

5. 解释可变和不可变 

 

StringBuilder sb = new StringBuilder();
System.out.println(sb.append("abc") == sb.append("def"));//true

 StringBuillder可变,在地址不变的情况下,内容是可变的。

 

6. StringBuffer概述

 基本方法和StringBuilder基本一样,包括追加和构造基本一样。
synchronized,按下不表,多线程部分重点。


7. String,StringBuilder,StringBuffer的区别与联系


String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象销毁。
StringBuffer类则代表一个字符序列可变的字符串,可以通过append、insert、reverse、setChartAt、setLength等方法改变其内容。一旦生成了最终的字符串,调用toString方法将其转变为String
JDK1.5新增了一个StringBuilder类,与StringBuffer相似,构造方法和方法基本相同。
不同是StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能略高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder
StringBuilder:JDK1.5开始效率高线程不安全
StringBuffer:JDK1.0开始效率低瞭线程安全
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值