包装类
包装类就是把基本数据类型封装到一个类中,并提供相应的属性和方法更方便的去操作基本数据类型。
切记,包装类不是为了取代基本数据类型。包装类位于java.lang包中,继承关系如下:
其中,Number是一个抽象类,提供了包装类和基本数据类型的装换。其中定义xxxValue()用于转换成基本数据类型。子类(Byte,Short,Integer,Long,Float,Double)是根据其自身特性实现xxxValue()方法。
Integer
Integer包装了一个基本数据类型,提供了很多方法能在int类型和String类型之间互相转换。
public class Test01 {
public static void main(String[] args) {
// 【1】静态字段属性
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
// 【2】构造方法
// int->Integer
Integer i1 = new Integer(10);
System.out.println(i1.toString());
// String->Integer
// 可能会抛出NumberFormatException
Integer i2 = new Integer("20");
System.out.println(i2);
}
}
常用方法
public class Test02 {
public static void main(String[] args) {
// 【1】xxxValue()
Integer i1 = new Integer("20");
int i1Value = i1.intValue();
System.out.println(i1Value);
// 【2】equals
Integer i2 = new Integer(10);
System.out.println(i1.equals(i2));
// 【3】String -> 基本数据类型
int a = Integer.parseInt("100");
// 把String按照进制解析(C)
int b = Integer.parseInt("1010", 2);
System.out.println(b);
// 把十进制转化成对于基数的字符串(C)
String str1 = Integer.toBinaryString(10);
System.out.println(str1);
// 【4】 基本数据类型 -> String
String str2 = Integer.toString(10);
System.out.println(str2);
// 【5】String、int -> Integer
Integer i3 = Integer.valueOf(100);
Integer i4 = Integer.valueOf("200");
System.out.println(i3);
System.out.println(i4);
}
}
总结
基本数据类型 <-> 包装类
Integer(int)
ValueOf(int)
xxxValue()
String <-> 包装类
Integer(String)
ValueOf(String)
toString();
基本数据类型 <- 包装类 -> String
static toString(int):String
static ParseInt(String):int
Comparable接口
这个接口提供了对两个对象进行自然排序(比较大小)。实现该接口的类具有比较大小的能力。其中定义的compareTo()用于比较大小,其返回值a.compareTo(b) -> r
public class Test03 {
public static void main(String[] args) {
Integer i1 = Integer.valueOf(20);
Integer i2 = Integer.valueOf(10);
System.out.println(i1.compareTo(i2));
}
}
自动拆箱和自动装箱
自动装箱:jvm编译时会把基本数据类型自动转化为对应的包装类,称为自动装箱(auto-boxing)
// 【1】 自动装箱
Integer i2 = 20; // Integer.valueOf(20);
System.out.println(i2.toString());
自动拆箱:jvm在编译时会把包装类自动转化成对应的基本数据类型,称为自动拆箱(auto-unboxing)
// 【2】 自动拆箱
int a = i2;
System.out.println(a);
String
String 类代表字符串。java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现。
- 字符串是常量;它们的值在创建之后不能更改。因为String对象是不可变的,所以可以共享。
- 字符连成一串构成了字符串,本质上,字符串就是字符数组。
- 字符数组长度不可变,同时String类没有提供修改字符数组的方法,所以字符串是常量。
构造方法
String提供了很多构造方法,其中可以根据字节数组构造字符串,也可以通过字符数组构造字符串。
// 【1】
// new 分配在堆区
String str1 = new String("hello");
// 常量池
String str2 = "hello";
System.out.println(str1 == str2);
// 通过字节数组构建字符串
byte[] buf3 = {97,98,99};
// win7简体中文 平台默认字符串
System.out.println(Charset.defaultCharset());
String str3 = new String(buf3);
System.out.println(str3);
// 通过指定字符集解码指定字节数组
// GBK字节序列
byte[] buf4 = {-42,-48,-71,-6};
// String str4 = new String(buf4,"GBK");
// 解码自定长度的字节数组
String str4 = new String(buf4, 0, 2, "GBK");
System.out.println(str4);
// UTF-8字节序列
byte[] buf5 = {-28, -72, -83, -27, -101, -67};
String str5 = new String(buf5, "UTF-8");
System.out.println(str5);
// 通过指定字符数组构建字符串
char[] cbuf6 = {'中','国','你','好'};
// String str6 = new String(cbuf6);
String str6 = new String(cbuf6,0,3);
System.out.println(str6);
常用方法:
字符串比较
// 【1】字符串的比较
String str2 = "abc";
String str3 = "aBc";
// 查看源代码:总结字符串比较规则
System.out.println(str2.compareTo(str3));
// 不区分大小写的比较
System.out.println(str2.compareToIgnoreCase(str3));
// 比较内容是否相等,只有当大小写完全一致才行
System.out.println(str2.contentEquals(str3));
// 重写Object equals
System.out.println(str2.equals(str3));
System.out.println(str2.equalsIgnoreCase(str3));
// 实战:控制台输入验证码
String str4 = "a1Bf";
System.out.println("请输入验证码:" + str4);
Scanner sc = new Scanner(System.in);
String iptStr = sc.next();
if(str4.equalsIgnoreCase(iptStr)) {
System.out.println("验证码正确");
}else {
System.out.println("验证码输入失败");
}
查找字符串(子串)
// 字符串连接(+)
String str1 = "hello";
String str2 = " world";
String str3 = str1.concat(str2);
System.out.println(str3);
// 查找子串
System.out.println(str3.contains("he2"));
// 以自定后缀结尾
System.out.println(str3.endsWith("ld"));
// 实战:检查文件是否是mp3文件
String fileName = "abc.mp3";
System.out.println(fileName.endsWith(".mp3"));
// 以指定前缀开始
fileName = "kal20190713.png";
System.out.println(fileName.startsWith("kal2019"));
// 从指定位置判断是否有前缀
System.out.println(fileName.startsWith("2019", 3));
// indexOf
String str4 = "hoello123";
// 从左向右查找指定字符第一个出现的位置,如果没查到返回-1
System.out.println(str4.indexOf('a'));
// 从左向右从指定位置开始查找指定字符第一个出现的位置,如果没查到返回-1
System.out.println(str4.indexOf('1', 5));
// 从左向右查找指定字符串第一个出现的位置,如果没查到返回-1
System.out.println(str4.indexOf("ll"));
//indexOf(String str, int fromIndex)
// lastIndexOf
// 从右向左查找指定字符第一个出现的位置,如果没查到返回-1
System.out.println(str4.lastIndexOf('o'));
// 从右向左查找指定位置指定字符第一个出现的位置,如果没查到返回-1
System.out.println(str4.lastIndexOf('o',2));
// lastIndexOf(String str)
// lastIndexOf(String str, int fromIndex)
// 通过正则表达式 匹配检测是否包含指定正则表达式的字符串
String str5 = "18620011234";
System.out.println(str5.matches("186d{8}"));
格式化字符串
// 字符串格式化
int a = 10;
int b = 2;
// format(String format, Object... args)
// ... 可变参数 jdk1.5 新特性
String str1 = String.format("%d / %d = %d", a,b,a/b);
System.out.println(str1);
int price = 998;
String str2 = String.format("¥ %d", price);
System.out.println(str2);
double price2 = 998.123;
// IllegalFormatConversionException
// String str3 = String.format("¥ %d", price2);
// 保留2位小数
String str3 = String.format("¥ %.2f", price2);
System.out.println(str3);
字符串编码成字节数组
public static void main(String[] args) {
// 字符串编码成字节数组
String str1 = "abc中国";
// GBK
byte[] buf1 = str1.getBytes();
System.out.println(Arrays.toString(buf1));
// 指定字符集
// UnsupportedEncodingException
byte[] buf2 = null;
try {
buf2 = str1.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(buf2));
}
字符串替换、分割
package com.kal3;
import java.util.Arrays;
public class Test05 {
public static void main(String[] args) {
// 替换字符串
String str1 = "hello world";
String str2 = str1.replace('o', 'x');
System.out.println(str2);
String str3 = str1.replace("ll", "xx");
System.out.println(str3);
// 正则替换
String str4 = "abc123abc";
// String str5 = str4.replaceAll("[a-z]{3}", "hello");
String str5 = str4.replaceFirst("[a-z]{3}", "hello");
System.out.println(str5);
// 实战:把电话号码中的-替换成空字符
String str6 = "186-2001-9812";
String str7 = str6.replaceAll("-", "");
System.out.println(str7);
// 分割字符串
String str8 = "186-2001-9812";
String[] str8Arr = str8.split("-");
System.out.println(Arrays.toString(str8Arr));
// 实战:快速构建一个数组,其中包含26个大写字母
String str9 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String[] str9Arr = str9.split("");
System.out.println(Arrays.toString(str9Arr));
// 需求:请产生验证码时,产生中文
}
}
其他的操作(子串、大小写转换、去空白)
// 【1】验证是否为空
System.out.println("12".isEmpty());
// 【2】求子串
String str1 = "abc456";
// beginIndex 开始位置
//String str2 = str1.substring(3);
// 含头不含尾
String str2 = str1.substring(3,4);
System.out.println(str2);
// 大小写
String str3 = "abc";
System.out.println(str3.toUpperCase());
String str4 = "ABc";
System.out.println(str4.toLowerCase());
/*String str5 = "a1Bf";
System.out.println("请输入验证码:" + str5);
Scanner sc = new Scanner(System.in);
String iptStr = sc.next();
if(str5.toLowerCase().equals(iptStr.toLowerCase())) {
System.out.println("验证码正确");
}else {
System.out.println("验证码输入错误");
}*/
// 去空白
String str6 = " abc ";
System.out.println(str6.length());
//中间的空格去不掉
System.out.println(str6.trim().length());
类型转化
通过静态方法String.valueOf()基本数据类型转化成字符串
public class Test07 {
public static void main(String[] args) {
String str1 = String.valueOf(10);
System.out.println(str1);
}
}
字符串中的陷阱
不可变字符串String进行任何方法的调用都会产生新字符串,所以在使用过程中一定防止以下情况产生,特别在循环中。
String str1 = "a";
str1 += "b";
StringBuffer和StringBuilder
StringBuffer和StringBuilder是字符串的可变版本。它们内部维护了一个“容器”,其提供了很多方法对“容器”中的字符进行增、删、改、查。
StringBuffer
线程安全的可变字符序列。
public static void main(String[] args) {
// string buffer
// 默认容器容量是容纳16个字符
StringBuffer sb = new StringBuffer();
// 【1】添加操作
sb.append("a");
sb.append("hello");
sb.append(4);
System.out.println(sb);
// 输出字符串长度
System.out.println(sb.length());
System.out.println(sb.capacity());
// 【2】insert
sb.insert(0, "ABC");
sb.insert(0, 10);
System.out.println(sb);
// 【3】拓容
sb.append("12345");
// System.out.println(sb.capacity());
}
- StringBuffer默认构造对象时容器容量是16个字符。
- 随着字符数量的增加、StringBuffer会自动扩容。
- 扩容的规则:随着向StringBuffer添加新元素,如果空间有余,直接添加;如果空间不足,按照oldLength*2 + 2的规则通过数组复制的方式扩容。
public static void main(String[] args) {
StringBuffer sb = new StringBuffer(30);
// System.out.println(sb.capacity());
sb.append("helloworld");
// 【1】删除
// sb.delete(0, 5);
// sb.deleteCharAt(0);
System.out.println(sb);
// 【2】手动扩容,不管原来多少,直接变成100,如果变小会输出原来的要缩短用setLength
sb.ensureCapacity(100);
System.out.println(sb.capacity());
// 【3】修改操作
sb.setCharAt(0, 'H');
System.out.println(sb);
// 【4】修改字符串的长度
// sb.setLength(5);
// 多用于清空操作
sb.setLength(0);
System.out.println(sb);
// 【6】自动缩短容器
sb.append("he");
sb.trimToSize();
System.out.println(sb.capacity());
}
StringBuilder
线程不安全的字符串可变序列,不保证同步。
StringBuffer和StringBuilder的区别?
StringBuilder:可变字符序列、效率高、线程不安全 jdk1.5
StringBuffer:可变字符序列、效率低、线程安全jdk1.0
日期时间类
计算机如何表示时间?
在计算机中,规定格林尼治(GMT)时间为世界协调时(UTC),其他地区的时间都是在UTC的基础上进行时区偏移得到的。
时间戳
Date在计算机表示日期时间类,位于java.util包中。
Date本质上是一个包装类,包装了一个long类型的值,表示Date对象距离历元经历的毫秒数(时间戳timestamp)。
public static void main(String[] args) {
// 【1】Date
Date date = new Date();
// Sat Jul 13 16:04:29 CST(China Standard Time) 2019
System.out.println(date.toString());
// 获取距离历元的毫秒数
long ts = date.getTime()
System.out.println(ts);
// 需求:创建一个时间表示明天的此刻
long ts2 = ts + 24 * 60 * 60 * 1000;
Date date2 = new Date(ts2);
System.out.println(date2);
// 需求:国庆距离现在有几天?
String datestr2 = "2020年2月25日";
SimpleDateFormat df2 =new SimpleDateFormat();
df2.applyPattern("yyyy年MM月dd日");
Date datestr3=null;
try {
datestr3=df2.parse(datestr2);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(datestr3.getTime());//转化为时间戳
long date4 = datestr3.getTime()-date2.getTime();
System.out.println(date4/1000/3600/24);
// 【2】时间的比较
// 需求:比较date和date2的大小
if(date.getTime() < date2.getTime()) {
System.out.println("date2 大");
}else {
System.out.println("date2 小");
}
System.out.println(date.before(date2));
System.out.println(date2.after(date));
System.out.println(date.compareTo(date2));
}
getTime()获取时间戳
setTime(long)设置日期时间对象的时间戳
日期时间格式化
public static void main(String[] args) {
// date
// 根据系统当前时区、当前时间创建一个对象
Date date1 = new Date();
//System.out.println(date1.toString());
// 需求:格式化时间为xxxx年xx月xx日 xx时xx分xx秒
// 把日期->日期字符串
SimpleDateFormat df = new SimpleDateFormat();
// df.applyPattern("yyyy年MM月dd日 HH时mm分ss秒.SSS");
df.applyPattern("yyyy年MM月dd日 HH时mm分ss秒");
String dateStr = df.format(date1);
System.out.println(dateStr);
// 把日期字符串->日期时间
String dateStr2 = "2019年07月13日";
/*
SimpleDateFormat df2 = new SimpleDateFormat();
df2.applyPattern("yyyy年MM月dd日");
*/
df.applyPattern("yyyy年MM月dd日");
Date date2 = null;
try {
date2 = df.parse(dateStr2);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date2);
}
Calendar
日历本质上是一个包装类,包装了个特定的瞬间(就是时间戳),且在日历内部提供了很多字段(YEAR、MONTH、DAY_OF_MONTH、HOUR等),这些字段已经在Calendar计算好存在Calendar对象的容器中,只需要开发者去Calendar对象去获取即可。