文章目录
九.java常用类
(1)String类的使用
/**
* String:字符串,使用一对""引起来表示
* 1.String声明在final的,不可被继承
* 2.String实现了Serializable接口:表示字符串是支持序列化的。
* 实现了Comparable接口:表示String可以比较大小
* 3.String内部定义了final char[] value用于储存字符串数据
* 4.String;代表不可变的字符序列。简称:不可变 性。
* 5,通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
* 6.字符串常量池中是不会存储相同内容的字符串的。
*
*/
public class StringTest {
@Test
public void test1(){
String s1="abc";//字面量的定义方式
String s2="abc";
s1="Hello";
System.out.println(s1);
System.out.println(s2);
}
/**
* String的实例化方式
* 方式一:通过字面量定义的方式
* 方式二:通过new+构造器的方式
*
* String s=new String("abc");方式创建对象,在内存中创建了几个对象
* 两个:一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"abc"
*
*/
@Test
public void test2(){
// 通过字面量定义的方式:此时的s1,s2的数据javaEE声明在方法区中的字符串常量池中。
String s1="javaEE";
String s2="javaEE";
// 通过new+构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
}
}
(2)String在内存中情況对比
/**
* 结论:
* 1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
* 2.只要其中有一个是变量,结果就在堆中(除非声明为final)
* 3.如果拼接的结果调用intern()方法,返回值就在常量池中
*
*
*/
public void test3(){
String s1="javaEE";
String s2="Hadoop";
String s3="javaEEHadoop";
String s4="javaEE"+"Hadoop";
String s5=s1+"Hadoop";
String s6="javaEE"+s2;
String s7=s1+s2;
System.out.println(s3 == s4);//true
System.out.println(s3 == s5);//false
System.out.println(s3 == s6);//false
System.out.println(s3 == s7);//false
System.out.println(s5 == s6);//false
String s8 = s5.intern();//返回值得到的s8使用的常量值中已经存在的"javaEEHadoop"(常量池中)
System.out.println(s3 == s8);//true
}
(3)String方法
什么情况下indexOf(str)和lastIndexOf(str)返回值相同:
情况一:存在唯一的 str
情况二:不存在str
public class StringMethodTest {
@Test
public void test1(){
String s1="helloWorld";
//1.测试字符串长度(length)
System.out.println(s1.length());//10
//2.返回某索引处的字符(charAt)
System.out.println(s1.charAt(5));//W
//3.判断是否是空字符(isEmpty)
System.out.println(s1.isEmpty());//false
//4.将所有String中的字符改写为小写(toLowerCase)
//5.将所有String中的字符改写为大写(toUpperCase)
String s2 = s1.toLowerCase();
System.out.println(s1);//s1不可变,仍然为原来的字符串
//6.返回字符串的副本,忽略前导空白和尾部空白(trim)
String s3 = " He llo World ";
String s4 = s3.trim();//He llo World;
//7.忽略大小写比较两个字符(equalsIgnoreCase)
String s5 = "hello World";
String s6 = "Hello World";
System.out.println(s5.equalsIgnoreCase(s6));//true
//8.比较两个字符串的大小(compareTo)
String s7 = new String("abe");
String s8 = "abc";
System.out.println(s7.compareTo(s8));//2 返回值为不同位上的字符ASCII的差
//9.返回一个新字符串。他是此字符串从beginIndex位置开始截取(substring(int beginIndex))
//10.返回一个新字符串。他是此字符串从beginIndex位置开始截取到endIndex(substring(int beginIndex,endIndex))
String s9 = "JAVA真有意思";
String s10= s9.substring(4);
String s11= s9.substring(0,4);//4表示到第四位之前截止
System.out.println(s10);//真有意思
System.out.println(s11);//JAVA
}
@Test
public void test2(){
String s1="HelloWorld";
//11.测试此字符串是否以指定的后缀结束(endsWith)
System.out.println(s1.endsWith("ld"));//true
//12.测试此字符串是否以指定的前缀开始(startsWith)
System.out.println(s1.startsWith("he"));//false
//13.测试此字符串从指定索引位置开始的字串是否为以指定的前缀开始(startsWith)
s1.startsWith("ll",2);//表示从位置2开始是否以ll开头。 //true
String s2="Wo";
//14.判断字符串中是否包含指定的字符串(contains)
System.out.println(s1.contains(s2));//true
//15.返回指定子字符串在此字符串中第一次出现的索引,未找到则返回 -1(indexOf)
System.out.println(s1.indexOf("Wo"));//5
//16.从指定位置开始寻找子字符串在此字符串中第一次出现的索引(indexOf)
System.out.println(s1.indexOf("Wo", 6));//从第六位开始寻找 //-1
//17.从此字符串的右边开始寻找出现指定字符串的索引,相当于从后往前找,也相当于寻找字串最后一次出现的位置(lastIndexOf)
System.out.println(s1.lastIndexOf("or"));//6 位置还是从前往后数的
//18.从此字符串的右边开始寻找出现指定字符串的索引,从指定的索引开始 "反向搜索" (lastIndexOf)未找到也是返回-1
System.out.println(s1.lastIndexOf("or", 6));//6
}
@Test
public void test3(){
String s1="北京上海深圳苏州";
//19.替换原有字符串中的指定字符(replace)
System.out.println(s1.replace("北", "南"));
}
}
(4)String与各种类型数组的转换
/** String与char[]之间的转换
*
*
* @author: ccw
* @date: 2022/4/25 14:35
*/
import org.junit.Test;
/**
* String--->char[]:调用String的toCharArray()方法
* char[]--->String:调用String构造器
*/
public class StringTest1 {
@Test
public void test1(){
String str1="abc123";
char[] charArray = str1.toCharArray();
for(int i=0;i< charArray.length;i++){
System.out.println(charArray[i]);
}
char[] arr=new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}
}
/**
* String与byte[] 字节数组 之间的转换
*
* 编码:String--->byte[]:调用String的getBytes()
* 解码:byte[]--->String:调用String的构造器
*
*
* 编码:字符串--->字节 (看得懂--->看不懂的二进制数)
* 解码:编码的逆过程:字节--->字符串(看不懂的二进制--->看得懂)
*
* 解码时,要求解码使用的字符集必须与编码时使用的字符集一致,否则会出现乱码。
*
*
* @author: ccw
* @date: 2022/4/25 15:12
*/
public class StringTest2 {
public void test1(){
String str1="abc123中国";
byte[] bytes = str1.getBytes();//使用默认的字符集进行编码
System.out.println(Arrays.toString(bytes));
String str2=new String(bytes);//使用默认的字符集进行解码
System.out.println(str2);
}
}
(5)StringBuffer,StringBuilder
String,StringBuffer,StringBuilder三者的异同?
String:不可变的字符序列; 底层使用char[]数组存储
StringBuffer:可变的字符序列; 线程安全的,但效率偏低;底层使用char[]数组存储
StringBuilder:可变的字符序列; JDK5.0新增; 线程不安全的,但效率偏高;底层使用char[]数组存储
开发中建议使用:StringBuffer(int capacity)或StringBuilder(int capacity)
(6)StringBuffer常用方法
public class StringBufferMethodTest {
@Test
public void test1(){
StringBuffer s1 = new StringBuffer("abc");
//用于字符串的添加,拼接(append)
s1.append(1);
s1.append('1');
System.out.println(s1);
//删除指定位置的内容(delete(int start,int end)),左闭右开
//例如删除s1(abc11)的 c1
System.out.println(s1.delete(2, 4));
//把[start,end)位置替换成str(replace)
s1.replace(1,2,"qw");
System.out.println(s1);
//在指定位置插入xxx(insert)
System.out.println(s1.insert(2, "hhh"));
//将当前字符串逆序:reverse()
System.out.println(s1.reverse());
}
}
(7)JDK8之前的日期时间API
/**
* JDK8之前日期和时间的测试
*
*/
public class DateTimeTest {
//1.System类中的currentTimeMillis()
@Test
public void test1(){
long timeMillis = System.currentTimeMillis();
//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
//称为时间戳
System.out.println(timeMillis);
}
/**
* 1.java.util.Date类
* (1)两个构造器的使用
*
* (2)两个方法的使用
* >toString():显示当前的年月日 时分秒
* >getTime():获取当前Data对象对应的毫秒数.(时间戳)
*
* 2.java.sql.Data对应着数据库中的日期变量(java.util.Date的子类)
*
* 3.SimpleDateFormat:对日期Data类的格式化和解析
* 两个操作:
* (1)格式化:日期-->字符串 format
* (2)解析:字符串-->日期 parse
*
* SimpleDateFormat的实例化
*
*
*
* 4.Calendar
*
*
*/
@Test
public void test2(){
//1.构造器一:Date():创建了一个对应了当前时间的Data对象
Date date1 = new Date();
System.out.println(date1.toString());
System.out.println(date1.getTime());//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差//1650958723305
//2.构造器二:创建指定毫秒数的Data对象
Date date2 = new Date(1650958723305l);
System.out.println(date2.toString());
}
@Test
public void testSimpleDataFormat() throws ParseException {
// SimpleDateFormat的实例化
SimpleDateFormat sdf = new SimpleDateFormat();//使用默认的构造器
// (1)格式化:日期-->字符串
Date date = new Date();
System.out.println(date);
String format = sdf.format(date);
System.out.println(format);
// (2)解析:字符串-->日期
String str = "22-4-27 上午10:49";
Date date1 = sdf.parse(str);
System.out.println(date1);
//指定的方式进行格式化:调用带参的构造器
// SimpleDateFormat的实例化
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//格式化
String format1 = sdf1.format(date);
System.out.println(format1);
//解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),否则就抛异常
Date date2 = sdf1.parse("2022-4-27 10:49:20");
System.out.println(date2);
}
}
(8)Calendar日历类的使用
/**
* Calendar日历类(抽象类)的使用
*
*
* @author: ccw
* @date: 2022/4/27 19:26
*/
public class CalendarTest {
@Test
public void testCalendar(){
//1.实例化
//方式一:创建其子类(GregorianCalendar)的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
//2.常用方法:
//get()
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//set()手动修改DAY_OF_MONTH的值
calendar.set(Calendar.DAY_OF_MONTH,23);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//add()手动增加DAY_OF_MONTH的值,减少就为负数
calendar.add(Calendar.DAY_OF_MONTH,3);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//getTime():日历类--->Date
Date date = calendar.getTime();
System.out.println(date);
//setTime():Date--->日历类
Date date1 = new Date();//获取当前时间
calendar.setTime(date1);
int days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
}
}
(9)JKD8中新日期API
JDK8之前的API主要问题
JDK8之后的处理
/**
* JDK8 之后的时间日期API测试
*
*
* @author: ccw
* @date: 2022/4/28 11:15
*/
/**
* LocalDate,LocalTime,LocalDateTime(使用频率最高)的使用
*/
public class JDK8DateTimeTest {
@Test
public void test1(){
//now():获取当前时间,日期,或当前时间加日期
LocalDate localDate=LocalDate.now();
LocalTime localTime=LocalTime.now();
LocalDateTime localDateTime= LocalDateTime.now();
System.out.println(localDate);
System.out.println(localTime);
System.out.println(localDateTime);
//of():设置指定的年月日,时分秒,没有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2022, 4, 28, 11, 27, 30);
System.out.println(localDateTime1);
//getXxx():获取localDateTime的属性
System.out.println(localDateTime.getYear());
System.out.println(localDateTime.getMonth());
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getMonthValue());//月份数字化
System.out.println(localDateTime.getMinute());
//体现不可变性(原来localDateTime内的数据不变)
LocalDateTime localDateTime2=localDateTime.withDayOfMonth(22);
System.out.println(localDateTime2);//22
System.out.println(localDateTime);//28
//plusXxx操作(在原有的基础上添加)
LocalDateTime localDateTime3=localDateTime.plusMonths(2);
System.out.println(localDateTime);
System.out.println(localDateTime3);
//minusXxx操作(在原有的基础上减)
LocalDateTime localDateTime4=localDateTime.minusDays(5);
System.out.println(localDateTime);
System.out.println(localDateTime4);
}
}
上述两种方法理解即可,第三种则需要重点掌握
(10)Comparable接口的使用
/**
* 一.java中的对象,正常情况下只能进行比较操作:==或!=。不能使用 > 或 < 的
* 但是在开发场景中,我们需要对多个对象排序,言外之意就需要比较对象的大小。
* 如何使用:使用两个接口中的任何一个:Comparable或Comparator
*
* Comparable接口的使用:
* 1.像String、包装类等实现了Comparable接口,重写了CompareTo(obj)方法,给出了比较两个对象大小的方式
* 2.像String、包装类重写CompareTo()方法以后,进行了从小到大的排序
* 3.重写CompareTo(obj)的规则
* 如果当前对象this大于形参对象obj,则返回正整数,
* 如果当前对象this小于形参对象obj,则返回负整数,
* 如果当前对象this等于形参对象obi,则返回零。
* 4.对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo()的方法。
* 在CompareTo(obj)方法中指明如何排序
*
*
* @author: ccw
* @date: 2022/4/28 16:37
*/
public class CompareTest {
/*
Comparable的使用举例 自然排序
*/
@Test
public void test1(){
String[] arr = {"AA", "CC", "MM","GG","JJ","DD"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
(11)Comparator接口的使用
/**
* Comparator接口的使用 定制排序
*/
public class ComparatorTest {
// 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码
// 或者实现了java.lang.Comparable接口的排序规则不适合当前的操作
// 那么可以考虑使用Comparator的对象来排序
// 重写compare(object o1,object o2)方法,比较o1和o2的大小:
// 如果方法返回正整数,则表示o1大于o2;
// 如果返回0,表示相等;
// 返回负整数,表示o1小于o2。
@Test
public void test1(){
String[] arr = {"AA", "CC", "MM","GG","JJ","DD"};
Arrays.sort(arr, new Comparator() {
//字符按照从大到小的顺序排列
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String && o2 instanceof String){
String s1 = (String) o1;
String s2 = (String) o2;
return -s1.compareTo(s2);
}
// return 0;
throw new RuntimeException("输入数据异常");
}
});
System.out.println(Arrays.toString(arr));
}
}
(12)Comparable与Comparator的使用的对比:
Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小
Comparator接口属于临时性的比较