单元测试&日期常用类&字符串常用类
学习目标
1.熟练使用单元测试
2.数量掌握日期类
3.熟练掌握字符串类String、StringBuffer、StringBuilder
一、单元测试
1.1 单元测试概述
java单元测试是最小的单元测试代码,单元测试针对单个java方法进行测试。
在之前的学习中我们使用main方法实现单元测试,但是一个类中main方法只能有一个,测试多个方法并不方便。
1.2 junit 单元测试
junit 是一个开源的java语言的单元测试框架;他的使用非常简单,我们参照如下案例学习即可。
示例1:单元测试使用
/**
* @Auther: 胖叔讲java
* 单元测试
*/
public class TestDemo {
public void method1(){
System.out.println("方法1");
}
public void method2(){
System.out.println("方法2");
}
@Before //在每个测试方法运行前都会调用被@Before注解修饰的方法
public void before(){
System.out.println("测试方法运行前运行");
}
@After //在每个测试方法运行后都会调用被@Before注解修饰的方法
public void after(){
System.out.println("测试方法运行前运行");
}
@Test // @Test注解标注的方法是测试方法,可独立运行,测试方法没有参数和返回值 alt+enter导入依赖导入包
public void test1(){
//测试方法1
method1();
}
@Test // alt+enter导入依赖导入包
public void test2(){
//测试方法1
method2();
}
}
总结:
- 使用测试方法需要导入依赖导入包,只需要加@Test注解,然后alt+enter就可
- 测试方法不能有参数,不能有返回值
- 常见注解有@Test @Before @After
二、日期常用类
日期类api设计结构如下:
- Timezone代表时区
- Calendar是日历类,GregorianCalendar是日历的子类
- java.util.Date是日期类
- java.sql.Date、java.sql.Time、java.sql.Timestamp是javautil.Date的子类;分别是日期、时间、时间戳类
- DateFormat是日期格式类、SimpleDateFormat是日期格式类的子类
2.1 Date 类
2.1.1 Date类基本使用
Date是日期类,Date的构造方法如下:
- Date(long date) 使用给定的毫秒时间价值构建 Date对象
- Date() 返回系统的当前时间
日期是有时间的起点的,以地理位置格林尼治时间1970-01-01 00:00:00 为标准,视为时间的起点;Date(long date) 指的是距离标准时间过了多少毫秒;
示例1:Date构造方法演示
@Test
public void DateConstructorTest(){
//创建日期对象,返回系统的当前时间
Date date = new Date();
System.out.println(date);
//创建距离格林尼治时间标准时间过了1000毫秒的日期
Date date2 = new Date(1000L);
System.out.println(date2);
}
Date的常用方法如下:
- after(Date when) 测试如果这个日期是在指定日期之后
- before(Date when) 测试如果这个日期是在指定日期之前
- getTime() 返回自1970年1月1日以来毫秒数
示例2:Date常用方法演示
@Test
public void DateMethodTest(){
//创建两个日期对象
Date date1 = new Date();
Date date2 = new Date(1000L);
//date1是否在date2之前
System.out.println(date1.before(date2));
//date1是否在date2之后
System.out.println(date1.after(date2));
//获得date2距离格林尼治时间过了多少毫秒
System.out.print(date2.getTime());
}
2.1.2 Date与子类之间的相互转换
Date的子类有java.sql.Date,java.sql.Time,java.sql.Timestamp;这三个子类都对应数据库的时间类型,我们只要学习Date和三个子类的相互转换就可以了;这个三个子类的日期如何添加到数据库,是后面jdbc学习的事情。
示例1:Date与子类之间的转换
@Test
public void DateType(){
//创建java.util.Date
Date date = new Date();
//将java.util.Date转为java.sql.Date,通过java.sql.Date的构造方法实现
java.sql.Date date2 = new java.sql.Date(date.getTime());
//java.sql.Date转java.util.Date ,向上转型即可。
Date date3 = date2;
//java.util.Date转java.sql.Time
Time time = new Time(date.getTime());
//time转java.util.Date
Date date4 = time;
//java.util.Date转java.sql.Timestamp
Timestamp timestamp = new Timestamp(date.getTime());
// timestamp 转date
Date date5 = timestamp;
}
2.2 SimpleDateFormat
SimpleDateFormat是日期格式类,它可以按照指定的格式将date对象格式为字符串;也可以按照指定的格式将字符串解析为Date
示例1:
@Test
public void SimpleDateFormatTest() throws Exception{
//创建日期
Date date = new Date();
//将日期格式为字符串
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String result = simpleDateFormat.format(date);
System.out.println(result);
//将字符串解析为date对象
String str = "2022-01-01 01:02:03";
Date date2 = simpleDateFormat.parse(str);
System.out.println(date2);
}
2.3 Calendar
Calendar是日历类,主要用于设置日历时间,获取日历时间等操作;日历类是一个抽象类,它提供两者方式创建实例;如下所示:
示例1:创建Calendar日历对象
@Test
public void CalendarTest(){
//获取实例对象:静态方法,推荐
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
//向上转型
Calendar calendar1 = new GregorianCalendar();
System.out.println(calendar);
}
示例2:设置日历时间、与获取日历时间
@Test
public void CalendarTest2(){
//1.创建对象
Calendar calendar = Calendar.getInstance();
//2.set方法设置日历信息 以 年月日时分秒
//设置年
calendar.set(Calendar.YEAR,2019);
//日历用0-11 表示 1-12月
calendar.set(Calendar.MONTH,1);
//设置日 一月中的天数
calendar.set(Calendar.DAY_OF_MONTH,8);
//设置一天中的小时数
calendar.set(Calendar.HOUR_OF_DAY,15);
//设置一小时的分钟数
calendar.set(Calendar.MINUTE,20);
//设置一分钟的秒数
calendar.set(Calendar.SECOND,58);
calendar.set(2018,1,2);
calendar.set(2017,1,2,22,20,20);
//3.get方法获取日历信息
System.out.println(calendar.get(Calendar.YEAR));
//日历用0-11 表示 1-12月
System.out.println(calendar.get(Calendar.MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
System.out.println(calendar.get(Calendar.MINUTE));
System.out.println(calendar.get(Calendar.SECOND));
//4.将日历转为日期
Date date = calendar.getTime();
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
//5.将日期转为日历
Calendar calendar1 = Calendar.getInstance();
// 设置日历时间为标准时间过了一秒钟
calendar1.setTime(new Date(1000L));
// 打印日历信息
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar1.getTime()));
}
2.4 小结
- 日期体系
- 日期按照指定格式格式字符串,解析字符串到日期
- 日历操作,日历转日期操作
三、String常用类
2.1 String类介绍
通过查看API我们了解到String类的描述信息如下
结合描述信息我们查看以下源码
得出如下结论:
- String类实现了序列化接口
Serializable
支持序列化和反序列化开发(序列化后面详细讲解) - String类实现了比较器接口Comparable 支持自然比较
- String类实现了字符序列化接口
CharSequence
底层采用字符序列存储数据 - String是一个final类,代表不可以有子类;而底层采取final char[] 存储字符串。由此可以推断出String类代表的是一个不可变字符序列
2.2 String类构造方法
String类常用构造方法如下:
- String() 创建一个空字符串
- String(byte[] bytes) 将byte数组按照平台默认编码转为字符串
- String(byte[] bytes, String charsetName) 将byte数组按照指定编码转为字符串
- String(byte[] bytes, int offset, int length) 将byte数组的部分内容按照平台默认编码转为字符串;需要设置开始下标,长度;
- String(byte[] bytes, int offset, int length, String charsetName) 将byte数组的部分内容按照指定编码转为字符串;需要设置开始下标,长度;
- String(char[] value) 将char数组转为字符串
- String(char[] value, int offset, int count) 将char数组的部分内容转为字符串;需要指定开始下标,长度;
示例1:String构造方法演示
@Test
public void StringConstructorTest() throws UnsupportedEncodingException {
//创建一个空字符串
String str = new String();
System.out.println(str);
//将byte数组按照指定编码转为字符串
byte[] bb = {97,98,99};
String str2 = new String(bb);
System.out.println(str2);
// 将byte数组按照指定编码转为字符串
String str3 = new String(bb,"gbk");
System.out.println(str3);
// 将byte数组的部分内容按照平台默认编码转为字符串;需要设置开始下标,长度;
String str4 = new String(bb,0,2);
System.out.println(str4);
//将byte数组的部分内容按照指定编码转为字符串;需要设置开始下标,长度;
String str5 = new String(bb,0,2,"utf-8");
System.out.println(str5);
//将char数组转为字符串
char[] cc = {'胖','叔'};
String str6 = new String(cc);
System.out.println(str6);
//将char数组的部分内容转为字符串;需要指定开始下标,长度;
String str7 = new String(cc,0,1);
System.out.println(str7);
}
2.3 字符串字面量与字符串对象的区别
像这种方式 String str = “abc” 定义的字符串叫字面量。
字符串底层final修饰char[],是存储在常量池中,是不可变的。
因此,String str1 = “abc”; String str2 = “abc” 都指向常量池中的内存地址;System.out.println(str1==str2);`结果返回true;内存地址是一样的。
示例1:字符串字面量比较
@Test
public void StringTest2(){
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2);
}
结果之所以是true,是因为字面量的存储是如下结构
示例2:字符串字面量与字符串对象比较
@Test
public void StringTest3(){
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2);
}
结果之所以是false,是因为字面量存储在常量池,对象存储在堆内存;内存结构如下:
示例3:字符串拼接
结论:
- 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
- 常量与字符串变量拼接会在堆内存创建对象
- 如果拼接的结果调用intern()方法,返回值就在常量池中
示例4:字符串拼接陷阱
@Test
public void StringTest5(){
String str1 = "abcd";
final String str2 = "ab";
final String str3 = "cd";
System.out.println(str1==str2+str3);
}
结果是true 因为str2、str3被final修饰是常量。
2.4 字符串常用方法
2.4.1 字符串的判断类方法
字符串根据某种条件进行判断,返回boolean类型的方法有:
- boolean equals(Object obj):比较字符串的内容是否相同
- boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
- int compareTo(String anotherString):按字典顺序比较两个字符串
- boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
- boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
- boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
- boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
示例1:字符串判断类方法
@Test
public void StringMethodTest1(){
String str = "abc";
String str2 = new String("abc");
String str3 = "ABC";
//比较字符串内容是否相等
System.out.println(str.equals(str2));
//忽略大小写比较字符串内容是否相等
System.out.println(str.equalsIgnoreCase(str3));
//比较字母的字典顺序
System.out.println("a".compareTo("b"));
//判断字符串是否以"a"开头
System.out.println(str.startsWith("a"));
//测试此字符串从指定索引开始的子字符串是否以指定前缀开始
System.out.println(str.startsWith("b",1));
//判断字符串是否以bc结尾
System.out.println(str.endsWith("bc"));
//判断字符串是否包含"b"
System.out.println(str.contains("b"));
}
2.4.2 字符串转换类方法
字符串转换大小写,转换byte、char数组等方法有:
- String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
- String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
- getBytes()使用平台的默认字符集将此
String
编码为 byte 序列,并将结果存储到一个新的byte 数组中。 - getBytes(Charset charset) 使用给定的 charset 将此
String
编码到 byte 序列,并将结果存储到新的 byte 数组。 - toCharArray() 将此字符串转换为一个新的字符数组。
示例2:字符串转换类方法
@Test
public void StringMethodTest2() throws Exception{
//字符串转大写
System.out.println("abc".toUpperCase());
//字符串转小写
System.out.println("ABC".toLowerCase());
//根据平台默认编码将字符串转为字节数组
byte[] bytes = "胖叔讲java".getBytes();
System.out.println(Arrays.toString(bytes));
//将字符串按照指定编码转为字节数组
byte[] bytes2 = "胖叔讲java".getBytes("gbk");
System.out.println(Arrays.toString(bytes2));
//将字符串转为char数组
char[] chars = "胖叔讲java".toCharArray();
System.out.println(Arrays.toString(chars));
}
2.4.3 字符串查找与截取类方法
字符串查找与截取类方法:
- String substring(int beginIndex):返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
- String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
- int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
- int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
- int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引
- int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
示例3:字符串查找与截取类方法
@Test
public void StringMethodTest3() {
String str = "胖叔讲java,胖叔讲java";
//从3下标开始截取字符串
System.out.println(str.substring(3));
//从0下标开始截取字符串,截取到3下标;包括开始下标,不包括结束下标
System.out.println(str.substring(0,3));
//获得叔第一次出现的索引
System.out.println(str.indexOf("叔"));
//返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
System.out.println(str.indexOf("叔",3));
//回指定子字符串在此字符串中最右边出现处的索引
System.out.println(str.lastIndexOf("叔"));
//返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
System.out.println(str.lastIndexOf("叔",3));
}
2.4.4 字符串替换类方法
字符串替换类常用方法如下:
- String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
- String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
- String replaceAll(String regex, String replacement) : 使 用 给 定 的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
- String replaceFirst(String regex, String replacement) : 使 用 给 定 的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
示例4:字符串替换类方法
@Test
public void StringMethodTest4() {
String str = "胖叔讲java,胖叔讲java";
//替换字符串
System.out.println(str.replace("java","JAVA"));
//根据正则表达式替换所有符合规则的内容,正则表达式先用,后面详细讲解
//[a-z]+ 正则表达式含义匹配a-z的字母出现一次或多次
System.out.println(str.replaceAll("[a-z]+","pangshu"));
//根据正则表达式替换第一个符合规则的内容,正则表达式先用,后面详细讲解
System.out.println(str.replaceFirst("[a-z]+", "pangshu"));
}
2.4.5 字符串其他常用方法
字符串其他类常用方法如下:
- int length():返回字符串的长度
- char charAt(int index): 返回某索引处的字符
- boolean isEmpty():判断是否是空字符串
- String trim():返回字符串的副本,忽略前导空白和尾部空白
- boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
- String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
- String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
示例5:字符串其他常用方法
@Test
public void StringMethodTest5() {
String str = "胖叔讲java";
//返回字符串长度
System.out.println(str.length());
//返回某索引处的字符
System.out.println(str.charAt(2));
//判断字符串是否为空
System.out.println(str.isEmpty());
//去掉字符的前后空格
System.out.println(" 胖叔讲 java ".trim());
//判断字符串是否匹配正则表达式 .+ 表示任意字符出现一次以上
System.out.println(str.matches(".+"));
//按照正则表达式分组
String str2 = "窗前明月光,疑是地上霜,举头望明月,低头思故乡";
//按照中文逗号分组,分三组
String[] strs = str2.split(",",3);
for(String s : strs){
System.out.println(s);
}
}
2.4.6 字符串方法注意
String底层是字符数组常量,因此String类的所有方法都不会改变源字符串,而是返回一个新的字符串。
示例1:String类方法不会改变源字符串,返回的是一个新字符串。
@Test
public void StringMethodTest6() {
String str = "abc";
String result = str.toUpperCase();
System.out.println(result);
System.out.println(str);
System.out.println(str.substring(1));
System.out.println(str);
String result2 = str.replace('c', 'C');
System.out.println(result2);
System.out.println(str);
}
2.5 小结
- 字符串的构造方法
- 字符串字面量与对象区别
- 字符串常用方法
四、StringBuffer与StringBuilder
4.1 StringBuffer与StringBuilder概述
StringBuffer:可变的字符序列;线程安全的,效率相对String高很多,相对StringBuilder会低一些;底层使用char[]存储。
StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储。
StringBuffer和StringBuilder作为参数传递时,方法内部可以改变值 。
StringBuffer和StringBuilder的方法一致,底层结构一样,唯一的区别是StringBuffer是线程安全的,StringBuilder是线程不安全的。
StringBuffer的常用构造方法如下:
- StringBuffer() 构造一个没有字符的字符串缓冲区,并构造了16个字符的初始容量。
- StringBuffer(int capacity) 构造一个没有字符的字符串缓冲区,并构造指定的初始容量。
4.2 StringBuffer的常用方法
StringBuffer的常用方法如下:
StringBuffer append(xxx)
:提供了很多的append()方法,用于进行字符串拼接StringBuffer delete(int start,int end)
:删除指定位置的内容StringBuffer replace(int start, int end, String str)
:把[start,end)位置替换为strStringBuffer insert(int offset, xxx)
:在指定位置插入xxxStringBuffer reverse()
:把当前字符序列逆转public int indexOf(String str)
返回第一次出现的指定子字符串在该字符串中的索引。public String substring(int start,int end)
返回一个新的String
,它包含此序列当前所包含的字符子序列。public int length()
返回长度(字符数)。public char charAt(int n )
返回此序列中指定索引处的char
值。public void setCharAt(int n ,char ch)
将给定索引处的字符设置为ch
。public String toString()
将StringBuffer类型转为String类型
示例1:
@Test
public void StringBufferMethodTest(){
//创建实例
StringBuffer sb = new StringBuffer();
//拼接字符串
sb.append(1);
sb.append(true);
sb.append("hello");
System.out.println(sb);
//从0下标删除到5下标,包含开始下标,不包含结束下标
sb.delete(1,5);
System.out.println(sb);
//替换内容,包含开始,不包含结束下标
sb.replace(1,5,"aaa");
System.out.println(sb);
//插入指定内容
sb.insert(1,"hello");
System.out.println(sb);
//字符串反转
sb.reverse();
System.out.println(sb);
//截取字符串,返回新的字符串
String result = sb.substring(0, 3);
System.out.println(result);
//将StringBuffer转为String类型
System.out.println(sb.toString());
}
总结:StringBuffer类的大部分方法都是操作原对象,改变原对象。
String、StringBuffer、StringBuilder三者的区别:
相同点:
1.String、StringBuffer、StringBuilder 三者都实现了字符序列接口,都满足了字符序列规范。
2.都被final修饰的类,禁止这三个类的方法被重写。
不同点:
1.String 底层采用的是final char[] 进行存储字符串,是不可变的字符序列,每次拼接字符串都会开辟新的内存空间。拼接字符串效率非常低下。
2.StringBuffer 底层采用char[] 进行存储字符串,数组的长度默认16。是可变的字符序列,StringBuffer对象会根据使用情况扩充字符缓冲(原来的2倍+2这种算法扩充)。拼接字符串效率较String来说提高很多。方法都是被synchronized修饰的,都是线程安全的。
3.StringBuilder和StringBuffer功能一样,只是底层方法没有被synchronized修饰,是线程不安全的,执行效率高于StringBuffer ;
4.所以开发一般对字符串的增加、删除、插入操作一般用StringBuffer效率更高,其他操作用String更为便。
五、总结
- 单元测试的使用
- 日期类常用对象
- String、StringBuffer、StringBuilder