常用类
String
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
/**
* TODO
* 字符串
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/02/15:55
*/
public class StringTest1 {
/**
* String:字符串,使用一对""来标识
* 1 String声明为final的,不可被继承
* 2 String实现了Serializable接口:表示字符串是支持序列化的
* 实现了Comparable接口:表示String可以比较大小
* 3 String内部定义了final char[] value用于存储字符串数据
* 4 String:代表了不可变的字符串序列:简称:不可变性
* 即两个指向同一个地址的静态字符串的String,其中一个String发生变化,并不会影响另一个String
* 1 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
* 2 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value
* 3 当调用String的repleace()方法修改指定字符串时,也需要重新指定内存区域赋值,不能使用原有的value
* 5 通过字面量的方式,(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中
* 6 字符串常量池中不会存储想同内容的字符串
*/
@Test
public void test1(){
String s1="abc";
String s2="abc";
System.out.println(s1 == s2);
s1="edf";
System.out.println(s2);
String s3=s1.replace("ed","bc");
System.out.println(s1);
System.out.println(s3);
s1+=s2;
System.out.println(s1);
System.out.println(s2);
}
/**
* TODO
* String的实例化方式
*
* 方式1 通过字面量定义的方式
* 方式2 通过new +构造器的方式
* 方式2在内存中创建了两个对象,一个是在堆空间中new的结构,另一个是char[]对应的方法区的字符串常量池中的结构
*/
@Test
public void Test2(){
//通过字面量定义的方式:此时的s1和s2的数据是方法区的字符串常量池中的地址
String s1="JavaEE";
String s2="JavaEE";
//通过构造器的方式,此时s3,s4中保存的地址值,是数据在堆空间开辟空间的地址
String s3=new String("JavaEE");
String s4=new String("JavaEE");
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s3 == s4);
Person p1=new Person("Tom",12);
Person p2=new Person("Tom",12);
System.out.println(p1==p2);
System.out.println(p1.name==p2.name);
p1.name="Jerry";
System.out.println(p1.name==p2.name);
}
/**
* 1 常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
* 2 只要其中有一个是变量,结果就在堆中
* 3 如果拼接的结果调用intern()方法,返回值就在常量池中
*/
@Test
public void test3(){
String s1="javaEE";
String s2="hadoop";
String s3="javaEEhadoop";
String s4="javaEE"+"hadoop";
String s5=s1+"hadoop";
String s6=s1+s2;
String s7=s6.intern();
//final修饰变为常量,放在常量池中
final String s8="hadoop";
String s9="javaEE"+s8;
System.out.println(s9==s3); //true
System.out.println(s3==s4);//ture
System.out.println(s3==s5);//false
System.out.println(s3 == s6);//false
System.out.println(s3 == s7);//true
System.out.println(s7 == s6);//false
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
String的不可变性体现
package com.xiazhui.exer;
import org.junit.jupiter.api.Test;
/**
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/02/16:56
*/
public class StringTest {
String str=new String("good");
char[] ch={'t','e','s','t'};
public void change(String str,char ch[]){
str="test ok";
System.out.println(str);
ch[0]='b';
}
public static void main(String[] args) {
StringTest stringTest = new StringTest();
stringTest.change(stringTest.str, stringTest.ch);
//字符串是不可变形,因此没有改变
System.out.println(stringTest.str);
System.out.println(stringTest.ch);
}
String中常用方法
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/02/17:22
*/
public class StringMethodTest {
/**
* int length() 返回字符串长度:return value.length
* char charAt(int index) 返回某索引出的字符 return value[index]
* boolean isEmpty() 判断是否为空
* String toLowerCase() 将String中的所有字符转换为小写
* String toUpperCase() 将String中所有字符转化为大写
* String trim() 返回字符串的副本,忽略前导空白和尾部空白
* String equals(Object obj) 判断两个字符串的内容是否相等
* String equalsIgnoreCase(String anothor) 比较两个字符串内容是否相等忽略大小写
* String concat(String str)将指定字符串连接到当前字符串的尾部
* int comapreTo(String anotherString)比较两个字符串的大小
* String subString(int beginIndex) 返回一个新的字符串,从beginIndex开始截取,0开始计数
* String subString(int beginIndex,int endIndex)返回一个新的字符串,从beginIndex->endindex,不包含endIndex
*/
@Test
public void test1(){
String s1=" efe e ";
System.out.println(s1.trim());
String s2="Abc";
String s3="abc";
System.out.println(s2.equalsIgnoreCase(s3));
System.out.println(s3.substring(1,2));
}
/**
* boolean endsWith(String suffix):测试字符串是否以指定的后缀结束
* boolean startsWith(String prefix):测试字符串是否以指定的前缀开始
* boolean startsWith(String prefix,int toffset)判断此字符串从指定索引开始的字符串是否以指定前缀开始
* boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,才返回true,
* int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引
* int indexOf(String str,int formIndex):返回指定字符串是从指定索引开始第一次出现的位置
* int lastIndexOf(String str):返回指定字符串在此字符串中最后一次出现的位置的索引
* int lastIndexOf(String str,int formIndex):返回指定字符串从指定位置反向查找第一次出现的位置
*/
@Test
public void test2(){
String str1="helloWorld";
System.out.println(str1.startsWith("ll",2));
System.out.println(str1.lastIndexOf("o"));
System.out.println(str1.lastIndexOf("f")==str1.indexOf("f"));
}
/**
* String replace(char oldChar,char newChar) 返回一个新的字符串,通过替换字符而来
* String replace(CharSequence target,CharSequence replacement) 返回一个新的字符串,由字符串替换而来
* String replaceAll(String regex,String replacement) 将字符串中符合正则regex的全部替换为replacement
* String replaceFirst(String regex,String replacement) 将字符串中符合正则regex的第一个替换为replacement
* boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式
* String[] split(String regex) 根据给定的正则表达式的匹配拆分此字符串
* String[] split(String regex,int limit) 根据给定的正则表达式来拆分字符串,最多不超过Limit个,超过了则剩下的都放在最后一个
*/
/**
* String和基本数据类型,包装类的转换
* char[] toCharArray() String和字符数组的转换
* byte[] getBytes() String和字节数组的转换,默认编码utf-8
* byte[]转化为String用构造器,第二个参数指定解码格式,默认utf-8
*/
@Test
public void test4() throws UnsupportedEncodingException {
String str1="123";
//使用包装类.parse类型(str)转化
int i = Integer.parseInt(str1);
//使用String.valueOf()转化
String str2 = String.valueOf(i);
System.out.println(str2);
//char[] toCharArray()
char[] charArray = str1.toCharArray();
System.out.println(charArray);
//字符数组到String通过构造器实现
String string = new String(charArray);
System.out.println(string);
String string1 = "abc123";
char[] chars = string1.toCharArray();
for (int j=1;j<3;j++){
char temp=chars[j];
chars[j]=chars[chars.length-j-1];
chars[chars.length-j-1]=temp;
}
System.out.println(chars);
//编码格式默认Utf-8
byte[] bytes = string1.getBytes(StandardCharsets.UTF_8);
System.out.println(Arrays.toString(bytes));
byte[] gbks = string1.getBytes("gbk");
System.out.println(Arrays.toString(gbks));
//解码默认Utf-8,第二个参数指定解码格式
String s = new String(bytes,"gbk");
System.out.println(s);
}
}
StringBuffer和StringBuilder常用方法
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
/**
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/06/16:45
*/
public class StringBufferBuilderTest {
/**
* String,StringBuffer,StringBuilder三者的异同
* 三者效率:StringBuilder>StringBuffer>String
* String: 不可变的字符序列
* StringBuffer:可变的字符序列:线程安全的,效率低(多线程使用)
* StringBuilder: 可变的字符序列:线程不安全。效率高
* 底层均用char[]。但String使用final修饰
*
* StringBuffer默认大小是16,如果超过,则会创建一个原大小乘2+2的char[],并将原数组复制过来
* 如果构造器内传入字符串,则创造一个字符串长度+16的char[]
* 也可以创建指定的char[]长度
*/
@Test
public void test1(){
StringBuffer stringBuffer = new StringBuffer("abc");
System.out.println(stringBuffer.length());
}
/**
* TODO
* StringBuffer常用方法
* StringBuffer append() 添加字符串到末尾
* StringBuffer delete(int start,int end) 删除指定位置的内容
* StringBuffer replace(int start,int end,Strint str)将[start,end)位置的字符串替换为str
* StringBuffer insert(int offset,xxx) 在指定位置插入指定结构
* StringBuffer reverse() 把当前字符串逆序
* public indexOf(String str)
* public String substring(int start,int end)
* public int length()
* public char charAt(int n)
* public void setCharAt(int n,char ch);
*
* 总结:
* 增 append(xxx)
* 删 delete(int start,int end)
* 改 setCharAt(int n,char ch) / replace(int start,int end,String str)
* 查 charAt(int n)
* 插 insert(int offset,xxx)
* 遍历 toString(),for+charAt()
*/
@Test
public void test2(){
StringBuffer s1 = new StringBuffer("abc");
s1.append(1);
s1.append('1');
s1.append(false);
System.out.println(s1);
String substring = s1.substring(1, 3);
System.out.println(s1);
System.out.println(substring);
}
}
StringBuffer/Builder和String之间的转化:
StringBuffer/Builder->String:使用toString,使用String的构造器
String->StringBuffer/Builder: 使用String的构造器
* StringBuffer默认大小是16,如果超过,则会创建一个原大小乘2+2的char[],并将原数组复制过来
* 如果构造器内传入字符串,则创造一个字符串长度+16的char[]
* 也可以创建指定的char[]长度StringBuffer(int capacity)
*/
Date
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
import java.util.Date;
/**
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/08/16:28
*/
public class DateTimeTest {
@Test
public void test1(){
long l = System.currentTimeMillis();
System.out.println(l);
}
/**
* java.util.Date类
* |---java.sql.Date工具类
* 1 两个构造器的使用
* 2 两个方法的使用
* >toString():显示当前的年,月,日,时,分,秒
* >getTime():获取当前Date对象对应的时间戳
* 3 java.sql.Date对应着数据库中的日期类型的变量
* >如何实例化 构造器new Date(long);
* >将java.util.Date对象转化为java.sql.Date对象
*/
@Test
public void test2(){
//构造器一:获取当前时间对应的Date对象
Date date1 = new Date();
System.out.println(date1.toString());
System.out.println(date1.getTime());
//构造器二:创建指定毫秒数的Date对象
Date date = new Date(date1.getTime());
System.out.println(date);
java.sql.Date date2=new java.sql.Date(date.getTime());
System.out.println(date2);
}
}
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
/**
* TODO
* 日期的四种获取方式
* 1 System.currentTimeMills()
* 2 java.util.Date和子类java.sql.Date
* 3 SimpleDateFormat
* 4 Calendar
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/10/18:51
*/
public class DateTimeTest {
/**
* 两个操作
* 1 格式化:日期--->字符串
* 2 解析:格式化的逆过程,字符串--->日期
* @throws ParseException
*/
@Test
public void test1() throws ParseException {
//按照指定的方式格式化和解析,调用带参的构造器
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(simpleDateFormat.format(System.currentTimeMillis()));
System.out.println(System.currentTimeMillis());
String time=simpleDateFormat.format(System.currentTimeMillis());
//将字符串解析为时间时,需要抛出异常ParseEception
System.out.println(simpleDateFormat.parse(time));
}
/**
* TODO
* 将字符串2020-09-08转化为java.sql.Date格式
*/
@Test
public void test2() throws ParseException {
String str="2020-09-08";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//将lang.Date转化为sql.Date。通过调用getTime方法获取时间戳再调用构造方法
Date date = new Date(simpleDateFormat.parse(str).getTime());
System.out.println(date);
}
/**
* TODO
* 1990-01-01开始打鱼,三天打鱼两天晒网,计算xxxx-xx-xx在打鱼还是晒网
*/
@Test
public void test3() throws ParseException {
String str1="1990-01-01";
String str2="2020-09-08";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date1 = simpleDateFormat.parse(str1);
java.util.Date date2 = simpleDateFormat.parse(str2);
System.out.println(((date2.getTime()-date1.getTime())/24/60/60/1000+1)%5>=3?"晒网":"打鱼");
}
/**
* TODO
* Calendar日历类的使用
*
* 实例化:1 创建子类(GregorianCalendar)的对象
* 2 调用静态方法getInstance(),返回的实际上也是GregorianCalendar
* 常用方法:
* 1 int get()获取时间
* 2 void set()设置时间
* 3 void add()添加时间
* 4 Date getTime() 日历类--->Date
* 5 void setTime() Date--->日历类
*/
@Test
public void test4(){
Calendar calendar = Calendar.getInstance();
//get()
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//修改之后所有都会改变
//set()
calendar.set(Calendar.DAY_OF_YEAR,50);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//add()
calendar.add(Calendar.DAY_OF_YEAR,3);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));
//getTime()
System.out.println(calendar.getTime());
//setTime()
calendar.setTime(new Date(System.currentTimeMillis()));
System.out.println(calendar.getTime());
}
/**
* 注意:
* 获取月份时:1月是0...12月是11
* 获取星期时: 周日是1 ...周六是7
*/
@Test
public void test5(){
//偏移量
Date date = new Date(2020 - 1900, 12 - 1, 8);
System.out.println(date);
}
/**
* TODO
* localTime,localDate,LocalDateTime的使用
* localDateTime使用最多
*
* now(): 获取当前时间,日期,日期+时间
* of(): 设置指定时间生成日期,没有偏移量
* getXxx():获取时间,没有偏移量
* withXxx(): 设置时间,不可变性,不改变原来的,生成新的
* plusXxx(): 对于时间设置加法(参数使用负号则变为减法)
* minusXxx(): 对于时间设置减法(参数使用符号则变为加法)
*/
@Test
public void test6(){
//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, 8, 11, 22, 49);
System.out.println(localDateTime1);
//getXxx()
System.out.println(localDateTime1.getYear());
System.out.println(localDateTime1.getMonth());
//withXxx()
LocalDateTime localDateTime2 = localDateTime1.withMonth(10);
System.out.println(localDateTime2.getMonth());
System.out.println(localDateTime1.getMonth());
//plusXxx()
LocalDateTime localDateTime3 = localDateTime1.plusMonths(3);
System.out.println(localDateTime3);
//minusXxx()
System.out.println(localDateTime3.minusMinutes(20));
}
/**
* TODO
* Instant的使用
*
* 1 now(): 获取本初子午线对应的标准时间
* 2 atOffset(): 设定时区获得时间
* 3 toEpochMilli():获得从1970-1-1到现在的毫秒数
* 4 ofEpochMilli(): 指定毫秒数获得时间
*/
@Test
public void test7(){
//now():获取本初子午线对应的标准时间
Instant instant = Instant.now();
System.out.println(instant);
//atOffset(): 设置时区偏移量获得时间
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
//toEpochMilli():获取从1970/1/1 00:00:00起的毫秒数
System.out.println(instant.toEpochMilli());
System.out.println(System.currentTimeMillis());
//ofEpochMilli():通过给定的毫秒数,获取Instant实例
Instant instant1 = Instant.ofEpochMilli(System.currentTimeMillis());
System.out.println(instant1);
}
/**
* TODO
* DateTimeFormatter的使用
* 1 格式化时间 日期-->String
* 1 预定义的标准格式
* ISO_LOCAL_DATE_TIME
* ISO_LOCAL_DATE
* ISO_LOCAL_TIME
* 2 本地化相关格式
* ofLocalizedDateTime
* ofLocalizedDate
* ofLocalizedTime
*
* 设置格式:
* FormatStyle.Long/FormatStyle.MEDIUM/FormatStyle.Short 适用于LocalDateTime
* FormatStyle.Long/FormatStyle.MEDIUM/FormatStyle.short/FormatStyle.FULL 适用于LocalDate
* 3 自定义的格式
* 2 解析时间 String-->日期
*/
@Test
public void test8(){
//格式化:日期-->字符串
DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
String str=isoLocalDateTime.format(now);
System.out.println(str);
//解析:字符串--->日期
TemporalAccessor temporalAccessor = isoLocalDateTime.parse("2022-08-11T23:35:49.555");
System.out.println(temporalAccessor);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
System.out.println(dateTimeFormatter.format(now));
System.out.println(dateTimeFormatter1.format(now));
//自定义的格式
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
String str1=dateTimeFormatter2.format(LocalDateTime.now());
System.out.println(dateTimeFormatter2.format(LocalDateTime.now()));
TemporalAccessor parse = dateTimeFormatter2.parse(str1);
System.out.println(parse);
}
}
Compare比较器
package com.xiazhui.java;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Comparator;
/**
* TODO
* Comparable和Comparator的使用
*
* Comparable和Comparator的使用对比:
* Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小
* Comparator接口属于临时性的比较
* @Author: xiazhui
* version 1.0
* @Date: 2022/08/12/9:27
*/
public class CompareTest {
/**
* Compare接口的使用举例:自然排序
* 1 像String,包装类等实现了Comparable接口,重写了compareTo(obj)方法
* 2 重写compareTo(obj)的规则:
* 如果当前对象this大于形参对象obj,则返回正整数
* 如果当前对象this小于形参对象obj,则返回负整数
* 如果当前对象this等于形参对象obj,则返回零
*/
@Test
public void test1(){
String[] arr=new String[]{"AA","CC","KK","MM","DD"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* Comparator接口的使用:定制排序
* 1 背景
* 当元素的类型没有实现java.lang.Comparable接口而有不方便修改代码
* 活着实现了java.lang.Comparable接口的排序规则不适合当前的操作
* 那么可以考虑使用Comparator的对象来排序
* 2 重写Comparator(Object obj1,Object obj2)
* 规则和comparable相同
*/
@Test
public void test2(){
Goods[] arr=new Goods[3];
arr[0]=new Goods("zz",24.6);
arr[1]=new Goods("bb",24.5);
arr[2]=new Goods("ff",22);
Arrays.sort(arr);
for (Goods goods : arr) {
System.out.println(goods);
}
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Goods && o2 instanceof Goods){
Goods goods1=(Goods) o1;
Goods goods2=(Goods) o2;
return -goods1.compareTo(goods2);
}
throw new RuntimeException("输入数据类型不对");
}
});
for (Goods goods : arr) {
System.out.println(goods);
}
}
}