一、包装类 - 引入
1、什么是包装类:
以前定义变量,经常使用基本数据类型
对于基本数据类型来说,它就是一个数,加点属性,加点方法,加点构造器将基本数据类型对应进行了一个封装,产生了一个新的类,---》包装类。int,byte..--->基本数据类型
包装类--->引用数据类型
2、对应关系:
基本数据类型 对应的包装类 继承关系
byte Byte ---》Number---》Object
short Short ---》Number---》Object
int Integer ---》Number---》Object
long Long ---》Number---》Object
float Float ---》Number---》Object
double Double ---》Number---》Object
char Character Object
boolean Boolean Object
3、已经有基本数据类型了,为什么要封装为包装类?
(1)java语言面向对象的语言,最擅长的操作各种各样的类。
(2)以前学习装数据的---》数组,int0]Stringldoublel StudentD
以后学习的装数据的---》集合,有一个特点,只能装引用数据类型的数据
4、是不是有了包装类以后就不用基本数据类型了?
不是
二、常用属性--常用构造器
【1】直接使用,无需导包:
java.lang
类 Integer
【2】类的继承关系:
java.lang.object
Liava.lang.Nmber
Ljava.lang. Integer
【3】实现接口:所有已实现的接口:
Serializable,Comparable<Integer)
【4】这个类被final修饰,那么这个类不能有子类,不能被继承:
publi finalc ass Integer
extends nuber
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类型作为构造器的参数
代码
public static void main(String[] args) {//主函数
//构造器
Integer i1= new Integer(12); //调用
System.out.println("i1.toString()");//输出12
}
结果
(2)String类型作为构造器的参数:
Integer i2= new Integer("12"); //调用
Integer i3= new Integer("abcdef");//调用方法
【9】包装类特有的机制:自动装箱、自动拆箱
代码
public class test01 {//创建类
public static void main(String[] args) {//主函数
//自动装箱:int--->Integer
Integer i =12; //Integer类型
System.out.println(i);//输出结果
//自动拆箱:Integer--->int
Integer i2 = new Integer(12);//int类型
int num = 12;//Integer--->int
System.out.println(i);//输出结果
}
}
结果
(1) 自动装箱 自动拆箱 是从jdk1.5以后新出的特征
(2)自动装箱 自动拆箱 :将基本数据类型和包装类进行快速的类型转换
可以自定义打断点测试是否走入valueOf方法中:
【10】常用方法:
代码
public class W10 {//创建类
public static void main(String[] args) {//主函数
// TODO Auto-generated method stub
//compareTo:只返回三个值:要么是0,-1,1
Integer i1=new Integer(value: 6); //传入值
Integer i2= new Integer(value: 12); //传入值
System.out.println(i1.compareTo(i2));//输出结果// return(x<y)?-1∶((x==y)? 0 :1);
}
}
结果
/*
* 返回一个表示指定的 int 值的 Integer 实例。如果不需要新的 Integer 实例,则
* 通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过
* 缓存经常请求的值而显著提高空间和时间性能。
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
可以看到对于范围在-128到127的整数,valueOf方法做了特殊处理。
采用IntegerCache.cache[i + offset]这个方法。
从名字,我们可以猜出这是某种缓存机制。
进一步跟踪IntegerCache这个类,此类代码如下
/*
* IntegerCache内部类
* 其中cache[]数组用于存放从-128到127一共256个整数
*/
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
这就是valueOf方法真正的优化方法,当-128=<i<=127的时候,返回的是IntegerCache中的数组的值;当 i>127 或 i<-128 时,返回的是Integer类对象。
三、日期相关类
代码
import java.util.Date; //导入java.util.Date类
public class DateAndTime { //创建主类
public static void main(String[] args) { //主方法
// TODO Auto-generated method stub
Date date = new Date(); // 创建Date对象date
String time = String.format("%tc", date); // 将date格式化
String form = String.format("%tF", date); //将date格式化
// 将格式化后的日期时间输出
System.out.println("全部的时间信息是:" + time); //输出全部信息
System.out.println("年-月-日格式:" + form); //输出年—月—日格式信息
}
}
结果
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); //输出format
无运行结果
Calendar
- Calendar是一个抽象类,不能直接创建对象,使用子类实现
- 可以使用静态方法Calendar.getInstance()创建。
- 常用方法:get(),set()
代码
package imoocweather;
import java.sql.Date;
import java.util.Calendar;
import java.util.Scanner;
public class deta {
public static void main(String[] args) {
//获取日期
System.out.println("请输入你想要查看的日期(提示:格式为1990-2-5):");
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"); //正常日期
}
}
}
结果
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);
方法二
//方式三:自定义格式
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);
三、Math类
常用方法
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));
代码
package imoocweather;
import java.util.Random;
public class deta {
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());
}
}
结果
五、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),比较两个字符串是否值相等,已被重写。
3.compareTo(String anotherString),对比两个字符串,实现了一个Comparable接口,需要重写compareTo方法,已被重写
String内存分析
String在常量池中放置了一个变量,如果后续有结果相同的变量那就不会在增加一个变量,比如String s = "abc";后续如果再来了一个String s1 = "ab"+"c",常量池中也只会有一个"abc",不会有两个。但是注意使用String(String original)构造的String对象则不同。StringBuilder类
可变字符串类有:StringBuilder类,StringBuffer类不可变字符串类:String类
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
六、StringBuffer、StringBuilder、 String 之间的关系
(1)操作少,数据少,用string。
(2)单线程,操作多,数据多,用stringBuilder。
(3)多线程,操作多,数据多,用stringBuffer
1. StringBuffer、 StringBuilder、 String 互相转换
StringBuffer类和StringBuilder 类都有toStringO方法,可以返回字符序列的字符串表示形式。这两个类在初始化的时候,可以通过字符串作为参数,指定初始化的字符序列内容。
StringBuffer、StringBuilder、String的不同之处
String只能赋值一次,每一次内容发生改变都生成了一个新的对象,然后原有的对象引用新的对象,所以说 String 本身是不可改变。每一次改变 String 的字符串内容,都会在内存创建新的对象,而每一次生成新对象都会对系统性能产生影响。
而StringBuffer和StringBuilder不同,每次操作都是对自身对象做操作,而不是生成新的对像,其所占空间会随着字符内容增加而扩充,做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。
StringBuffer 和 StringBuilder 也存在不同之处。
StringBuffer的方法都使用"synchronized”关键字进行修饰,这样保证了同时最多只有一个线程可以运行这些方法,也就是保证了线程安全。 StringBuilder则不具备这样的特点。反过来说,正因为StringBuilder 没有线程安全机制,运行起来就不用考虑给线程加锁,所以运行效率会比 StringBuffer 要高。
小总结
1.String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象销毁。
2.StringBuffer类则代表一个字符序列可变的字符串,可以通过appendinsertreverse、setChartAtsetLength等方法改变其内容。一旦生成了最终的字符串,调用toString方法将其转变为String
3.JDK1.5新增了一个StringBuilder类,与StringBuffer相似,构造方法和方法基本相同。不同是StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能略高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder
StringBuilder:JDK15开始效率高线程不安全
StringBuffer:JDK1.0开始 效率低线程安全