文章目录
13.1 包装类
13.1.1 包装类的分类 WrapperType
- 针对八种基本数据类型相应的引用类型 - 包装类
- 有了类的特点,就可以调用类中的方法
- 如图:
13.1.2 包装类和基本数据类型的转换
- jdk5前的手动装箱和拆箱方式,装箱:基本类型 -> 包装类型,反之,拆箱
- jdk5(含)的自动装箱和拆箱方式
- 自动装箱底层调用的是valueOf方法,如Integer.valueOf();
- 以int和Integer为例,其他类似
13.1.3 案例
public class Integer {
public static void main(String[] args) {
//手动装箱
int n1 = 10;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱
int i = integer.intValue();
//自动装箱
int n2 = 200;
Integer integer2 = n2;//底层使用的仍是Integer.valueOf(n2);
//自动拆箱
int n3 = integer2;//底层使用的仍是intValue()方法
}
}
13.1.4 包装类型和String类型的相互转换
//以Integer和String为例
public class WrapperVsString {
public static void main(String[] args) {
Integer i = 100;
//包装类 - > String
//方式1
String str1 = i + "";
//方式2
String str2 = i.toString();
//方式3
String str3 = String.valueOf(i);
String str4 = "12345";
//String - > 包装类
//方式1
Integer i2 = Integer.parseInt(str4);//使用到自动装箱,Integer.parseInt(str4)是一个int
//方式2
Integer i3 = new Integer(str4);//构造器
}
}
13.1.5 Integer类和Character类常用方法
public class WrapperMethod {
public static void main(String[] args) {
System.out.println(Integer.MIN_VALUE);//返回最小值,int范围里面那个最小的
System.out.println(Integer.MAX_VALUE);
System.out.println(Character.isDigit('a'));//判断是否为数字
System.out.println(Character.isLetter('a'));//判断是否为字母
System.out.println(Character.isUpperCase('a'));//判断是否为大写
System.out.println(Character.isLowerCase('a'));//判断是否为数字
System.out.println(Character.isWhitespace('a'));//判断是否是空格
System.out.println(Character.toUpperCase('a'));//转成大写
System.out.println(Character.toLowerCase('a'));//转成小写
}
}
13.1.6 Integer类面试题
public class WrapperExercise {
public static void main(String[] args) {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j);// F 比较的是两个对象
//源码—— i 在【-128 ~ 127】直接返回,否则就new Integer(i)
Integer x = 128;//直接赋值,底层Integer.valueOf(128),看源码
Integer y = 128;
System.out.println(x == y);// F
Integer x1 = 45;//在范围内
Integer y1 = 45;
System.out.println(x1 == y1);// T
Integer a = 128;
int b = 128;
System.out.println(a == b);//T 只要有基本数据类型,判断的是值是否相等
}
}
13.2 String类
13.2.1 String类的理解和创建对象
- String对象用于保存字符串,也就是一组字符序列
- 字符串常量对象是用双引号括起的字符序列
- 使用Unicode编码,一个字符占两个字节
- 常用构造器
String s1 = new String();
String s2= new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a, int startlndex, int count);
- String 是 final 类,不能被继承
- String有属性private final char value[]; 用于存放字符串内容
- value是一个final类型,不可以修改,即不能指向新的地址。但是单个字符内容是可变的
13.2.2 创建String对象两种方式
- 直接赋值:String s = “xxxx”;
- 调用构造器:String s = new String(“xxxx”);
13.2.3 两种方式区别
- 直接赋值:先从常量池查看是否有"xxxx"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。是直接指向常量池的空间地址的。
- 调用构造器:先在堆中创建空间,里面维护了value属性,指向常量池的"xxxx"空间。如果常量池没有则重新创建,如果有,则直接通过value指向。是指向堆中的value地址
......
String a = "hsp";// a 指向 常量池
String b = new String("hsp");// b 指向 堆
System.out.println(a.equals(b));//T
System.out.println(a == b);//F
System.out.println(a == b.intern());//T b.intern()最终指向的是常量池
System.out.println(b == b.intern());//F
//当调用intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定
//则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用
......
13.3 字符串的特性
- String是一个final类,代表不可变的字符序列
- 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的
String s1 = “hello”;
s1 = “haha”;
上面代码共创建了两个对象,刚开始s1指向池中的hello,后面断开,指向池中的haha
String a = “hello”;
String b = “aas”;
String c = a + b
上面创建了三个对象
String str = “hello” + “and”;
创建了一个对象
13.4 String类的常见方法
13.4.1 说明
String类是保存字符串常量的。每次更新都需要重新开辟空间,效率低。
13.4.2 常见方法
- equals 区分大小写,判断内容是否相等
- equalslgnoreCase 忽略大小写,判断内容是否相等
- length
- indexOf 获取字符在字符串中最后1此出现的索引,索引从0开始,找不到返回-1
- lastlndexOf
- substring 截取指定范围的子串(3)从索引3开始截取后面所有 (3,6)索引3截取到索引5
- trim 去前后空格
- charAt 获取某索引处的字符,注意不能使用Str[index]这种方式
- toUpperCase 转大写
- toLowerCase 转小写
- concat 拼接字符
- replace 替换字符串中的字符,返回的结果是替换过的,对最初的没影响
- split 分割字符串,返回数组。对于某些分割字符,我们需要转义 如 \ |
- compareTo 比较两个字符串的大小。长度内容都相等返回0;长度相等,部分内容相等返回长度差;长度相等内容不相等返回字符差
- toCharArray 转换成字符数组
- format 格式字符串,%s字符串、%c字符、%d整型、%.2f 浮点型
String formatStr = “名字%s年龄%d,成绩%.2f性别%c”;
String info = String.format(formatStr, name, age, score, gender);
输出info
13.5 StringBuffer类
13.5.1 基本介绍
- java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删,因为其父类有属性 char[] value,不是 final。不用每次更换地址(即创建新对象),所以效率比String高。
- 很多方法与String相同,但StringBuffer是可变长度的
- StringBuffer是一个容器
13.5.2 String VS StringBuffer
- String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率低 private final char value[]
- StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址。 char[] value
13.5.3 String和StringBuffer相互转换
public class StringAndStringBuffer {
public static void main(String[] args) {
//String - > StringBuffer
String str = "hello tom";
// 1 构造器 返回的才是StringBuffer对象,对原来的str无影响
StringBuffer stringBuffer = new StringBuffer(str);
// 2 append方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1 = stringBuffer1.append(str);
//StringBuffer - > String
StringBuffer stringBuffer2 = new StringBuffer("ahc");
// 1 使用StringBuffer提供的toString方法
String s = stringBuffer2.toString();
// 2 构造器
String s1 = new String(stringBuffer2);
}
}
13.5.4 StringBuffer常见方法
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增
s.append(',');
s.append("赵敏").append("张三丰").append("黄飞鸿");
//删
//删除索引为[start,end)字符
s.delete(11, 14);
//改
s.replace(9, 11, "周芷若");//用周芷若,替换[9,11)字符
//查
int index = s.indexOf("张三丰");//index为张三丰第一次出现的索引,找不到返回-1
//插
s.insert(9, "赵敏");//在索引9前面插入赵敏
//长度
s.length();
}
}
13.6 StringBuilder类
13.6.1 基本介绍
- 一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的一个简易替换,**用在字符串缓冲区被单个线程使用的时候。**如果可能,建议优先采用该类,因为在大多数实现中,他比StringBuffer要快。
- 在StringBuilder上的主要操作是append和insert方法,可重载这些方法以接收任意类型的数据
13.6.2 String、StringBuffer和StringBuilder的比较
- StringBuilder和StringBuffer非常类似,均代表可变的字符序列,且方法一样
- String:不可变字符序列,效率低,但复用率高
- StringBuffer:可变字符序列、效率较高(增删)、线程安全
- StringBuilder:可变字符序列、效率最高、线程不安全
- String使用注意说明:
string s = “a”; //创建了一个字符串
s += “b”; //实际上原来的"a"字符串对象已经丢弃了,现状又产生了一个字符串s + “b”(“ab”)。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放在循环中,会极大影响程序的性能。
结论:如果要对String做大量修改,建议不要使用String
13.6.3 三者选择
- 如果字符串存在大量的修改操作,一般使用StringBuffer或StringBuilder
- 如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder
- 如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
- 如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等
13.7 Math类
13.7.1 基本介绍
Math类包含用于执行基本属性运算的方法,如初等指数、对数、平方根和三角函数
13.7.2 方法一览(均为静态方法)
13.7.3 Math类常见方法
public class MathMethod{
public static void main(String[] args) {
//绝对值
int abs = Math.abs(-9);
//幂
double pow = Math.pow(2, 4);//2的4次方
//向上取整,返回≥该参数的最小整数(double)
double ceil = Math.ceil(3.9);
//向下取整,返回≤该参数的最大整数(double)
double floor = Math.floor(4.001);
//四舍五入
long round = Math.round(5.51);
//开方
double sqrt = Math.sqrt(9.0);
//随机数
Math.randow();// 生成[0,1)之间的随机小数
//返回a - b自建随机数,公式:(int)(a + Math.randow() * (b - a + 1))
//如生成2 - 7的100个随机数
for(int i = 0; i < 100; i++) {
System.out.println((int)(2 + Math.randow() * 6));
}
}
}
13.8 Arrays类
13.8.1 常见方法
Arrays里面包含了一系列静态方法,用于管理或操作数组
- toString 返回数组的字符串形式。Arrays.toString(arr);
- sort排序(自然和定制排序)Integer arr[] = (1, -1, 7, 0};
- binarhSearch通过二分搜索法进行查找,要求必须先排好序
int index = Arrays.binarySearch(arr,3); - copyOf 数组元素复制 Integer[] newArr = Arrays.copyOf(arr, arr.lengeh);
- fill数组元素的填充 Integer[] num = new Integer[]{9, 3, 2}; Arrays.fill(num, 99);
- equals 比较两个元素内容是否完全一致 boolean equals = Arrays.equals(arr, arr2);
- asList将一组值,转换成list。 List asList = Arrays.asList(2, 3, 4, 5);
public class ArraysMethod {
public static void main(String[] args) {
Integer[] integers = {1, 20, 90};
//toString方法,就不用在遍历显示数组元素了
System.out.println(Arrays.toString(integers));
//sort方法
Integer[] arr = {1, -1, 7, 0, 89};
/*
解读:
1. sort方法可以代替冒泡排序
2. 排序后会直接影响实参arr,因为数组是引用类型
3. sort重载的,也可以通过传入一个接口Comparator实现 定制排序
4. 定制排序传入的两个参数:1)数组arr 2)实现了Comparator接口的匿名内部类,实现compare方法
*/
//默认排序
Arrays.sort(arr);
//定制排序
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return i2 - i1;//决定排序方式
}
});
Arrays.toString(arr);
}
}
深入理解定制排序
public class ArraySortCustom {
publc static void main(String[] args) {
int[] arr = {1, -1, 8, 0, 20};
bubble01(arr);//只能按照一种方式排序
bubble02(arr, new Comeparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer)o1;//向下转型,在拆箱
int i2 = (Integer)o2;
return i1 - i2;//这里控制排序方式,不用去更改bubble02方法
}
}
}
//原始方法,冒泡
public static void bubble01(int[] arr) {
int temp = 0;
for(int i = 0; i < arr.length - 1; i++) {
for(int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j} > arr[j + 1]) {//要通过这里改变,才能改变排序方式
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//冒泡 + 定制
public static void bubble02(int[] arr, Comparator c) {
int temp = 0;
for(int i = 0; i < arr.length - 1; i++) {
for(int j = 0; j < arr.length - 1 - i; j++) {
if(c.compare(arr[j}, arr[j + 1]) > 0) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
public class ArraysMethod02 {
public static void main(String[] args) {
Integer[] arr = {1, 2, 90, 123, 567};
//二分搜索法(有序的数组)
int index = Arrays.binarySearch(arr, 567);//未找到返回 -(low + 1);即因该在的位置+1的负数
//数组元素复制
Integer[] newArr = Arrays.copyOf(arr, arr.length);//拷贝长度大于arr.length,后面补null;小于0,异常
//数组元素填充
Integer[] num = new Integer[]{9, 3, 2};
Arrays.fill(num, 99);
//比较数组元素内容
Integer[] arr2 = {1, 2, 90, 123};
Arrays.equals(arr, arr2);
//将一组值,转换成list
Arrays.asList(2, 3, 4, 5);
}
}
13.9 System类
13.9.1 System类常见方法
- exit 退出当前程序
- arraycopy:复制数组元素,比较适合底层调用,一般使用Arrays.copyOf完成复制
int[] src = {1, 2, 3};
int[] dest = new int[3];
System.arrycopy(src, 0, dest, 0, 3);
- currentTimeMillens: 返回当前时间距离1970-1-1的毫秒数
- gc:运行垃圾回收机制 System.gc();
public class Systema_ {
public static void main(String[] args) {
//退出当前程序
System.exit(0);//0表示一个状态,正常的状态
//数组元素复制
int[] src = {1, 2, 3};//源数组
int[] dest = new int[3];//目标数组
System.arraycopy(src, 0, dest, 0, src.length);//从src的索引为0的位置开始给dest的索引为0的位置开始复制,复制长度为src.length
//返回至1970-1-1毫秒数
System.currentTimeMillis();
}
}
13.10 BigInteger 和 BigDecimal 类
13.10.1 介绍
应用场景:
- BigInteger适合保存比较大的整形
- BigDecimal适合保存精度更高的浮点型
13.10.2 常见方法
- add
- subtract
- multiply
- divide
public class BigInteger_ {
public static void main(String[] args) {
//long 不够用
BigInteger bigInteger = new BigInteger("999999999999999999999999999999");
BigInteger bigInteger2 = new BigInteger("888888888888888888888888888888");
//BigInteger运算时,不能直接使用加减乘除,要使用方法
BigInteger add = bigInteger.add(biInteger2);
BigInteger subtract = bigInteger.subtract(biInteger2);
BigInteger multiply = bigInteger.multiply(biInteger2);
BigInteger divide = bigInteger.divide(biInteger2);
}
}
public class BigDecimal_ {
public static void main(String[] args) {
//double 不够用
BigDecimal bigDecimal = new BigDecimal("4.5555555555555");
BigDecimal bigDecimal2 = new BigDecimal("3");
//运算
bigDecimal.add(bigDecimal2);
bigDecimal.subtract(bigDecimal2);
bigDecimal.multiply(bigDecimal2);
bigDecimal.divide(bigDecimal2);//可能抛出异常,需指定精度
bigDecimal.divide(bigDecimal2, BigDecimal.ROUND_CEILING);//如果为无线循环小数,会保留分子的精度
}
}
13.11 日期类
13.11.1 第一代日期类
- Date:精确到毫秒,代表特定的瞬间
- Simple Date Format:格式和解析日期的类,允许进行格式化和规范化
public class Date01 {
public static void main(String[] args) {
//这里的Date类在util包
Date d1 = new Date();//获取当前系统时间
Date d2 = new Date(9235567);//通过指定毫秒数得到时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");//固定格式化,字母不能乱写
String format = sdf.format(d1);//将日期转成指定格式的字符串
//格式化的String转回Date
String s = "1996年01月01日 10:20:30 星期一";//需要与定义的sdf格式一样
Date parse = sdf.parse(s);
sdf.format(parse);
}
}
13.11.2 第二代日期类
- Calendar类(日历)
public abstract class Calendar extends Object implements Serializable,Cloneable,Comparable
- Calendar 类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法
public class Calendar_ {
public static void main(String[] args) {
/*
Calendar是一个抽象类,且构造器私有化,需通过get方法获取实例
没有格式化功能,需自己组合
24小时制:Calendar.HOUR 改为 Calendar.HOUR_OF_DAY
*/
Calendar c = Calendar.getInstance();//创建日历对象
//获取日历对象某个日历字段
c.get(Calendar.YEAR);
c.get(Calendar.MONTH) + 1;//因为月从0开始编号,所以 +1
c.get(Calendar.DAY_OF_MONTH);
c.get(Calendar.HOUR);
c.get(Calendar.MINUTE);
c.get(Calendar.SECOND);
//如需格式化,自己组合
}
}
13.11.3 第三代日期类
前两代不足:
JDK1.0中包含了一个java.util.Date类,但大多数方法在JDK1.1引入Calendar类后被弃用,而Calendar也存在问题:
- 可变型:像日期和时间这样的类应该是不可变的
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始
- 格式化:只对Date有用,Calendar没有格式化功能
- 他们都不是线程安全的;不能处理闰秒等(每隔2天,多出1s)
第三代
- LocalDate 只包含日期,可以获取日期字段
- LocalTime只包含时间,可以获取时间字段
- LocalDateTime包含日期和时间,可以获取日期和时间字段
public class LocalDate_ {
public static void main(String[] args) {
//now() 返回单曲日期时间的对象
LocalDateTime ldt = LocalDateTime.now();
//DateTimeFormat格式化
DateTimeFormat dateTimeFormat = DateTimeFormat.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormat.format(ldt);
//调用字段
ldt.getYear();
ldt.getMonth();
ldt.getMonthValue();
//另外2种
LocalDate now = LocalDate.now();//年月日
LocalTime now2 = LocalTime.now();//时分秒
//时间加减
LocalDateTime localDateTime = ldt.plusDays(890);//890天后的时间
LocalDateTime localDateTime2 = ldt.minusMinutes(890);//890分钟前的时间
}
}
13.11.4 格式日期类
看上面代码
13.11.5 Instant时间戳
类似于Date,提供了一系列和Date类转换的方式
Instant -> Date
Date date = Date.from(instant);
Date -> Instant
Instant instant = date.toInstant();
public class Instant_ {
public static void main(String[] args) {
//通过静态方法now()获取表示当前时间戳的对象
Instant now = Instant.now();
//通过from把Instant -> Date
Date date = Date.from(now);
//通过date的toInstant()把Date -> Instant
Instant instant = date.toInstant();
}
}
13.11.6 第三代日期类更多方法
- LocalDateTime类
- MonthDay类:检查重复事件
- 是否为闰年
- 增加日期的某个部分
- 使用plus方法测试增加时间的某个部分
- 使用minus方法测试查看一年前和一年后的日期
- 其他看API