JAVA常用类
字符串相关的类
String类
-
代表字符串,Java程序中的所有字符串字面值都作为此类的实例实现
-
String是一个final类,代表不可变的字符序列
示例:
- 当对字符串重新赋值时,需要重写制定内存区域赋值,不能使用原有的value进行赋值
public class Test01 { @Test public void test1(){ String s1 = "abc"; //字面量的定义方式 //s1 = "hello"; String s2 = "abc"; System.out.println(s1 == s2);//比较s1和s2的地址值 //输出为true System.out.println(s1); System.out.println(s2); } }
-
当对现有的字符串进行连接(替换某一字符同理)操作时,也需要重新指定内存区域赋值
String s3 = "abc"; s3 += "def"; System.out.println(s3);//输出是abcdef System.out.println(s2);//输出是abc
-
字符串是常量,用双引号引起来表示,它们的值在创建后不氪更改
-
String对象的字符内容是储存在一个字符数组value中的。
-
String实现了Serializable接口,表示字符串是支持序列化的
-
String实现了Comparable接口
面试题:String s = new String(“abc”);方式创建对象,在内存中创建了几个对象?
两个:一个是堆空间的new结构,一个是char[]对应的常量池中的数据
- 结论:
- 常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
- 只要有其中一个是变量,结果就在堆中
- 如果拼接的结果调用intern()方法,返回值就在常量池中。
String类常用方法
见另一篇文章:https://blog.csdn.net/Connor66/article/details/120811261
StringBuffer、StrinngBuilder
-
StringBuffer 可变的字符序列 线程安全的,效率低
-
StrinngBuilder 可变的字符序列 jdk5.0新增的,线程不安全的,效率高
-
常用方法:
public void test2(){ StringBuffer s1 = new StringBuffer("abcde"); s1.append(1); s1.append("2");//添加字符 System.out.println(s1);//abcde12 s1.delete(2,4);//删除指定位置的内容左闭右开 System.out.println(s1);//abe12 s1.replace(2,4,"hello");//将指定位置的内容进行替换 System.out.println(s1);//abhello2 s1.insert(2,"333");//在指定位置插入字符串 System.out.println(s1);//ab333hello2 s1.reverse();//反转 System.out.println(s1);//2olleh333ba String s2 = s1.substring(0, 3);//返回一个左闭右开区间的子字符串 System.out.println(s2);//2ol }
JDK8之前的日期时间API
-
System类中的currentTimeMillis()方法
@Test public void test1(){ long time = System.currentTimeMillis(); //返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差 //称为时间戳 System.out.println(time); }
-
java.util.Date类
- toString()显示当前年月日时分秒
Date date1 = new Date(); System.out.println(date1.toString());
结果为:
Wed Oct 20 19:14:34 GMT+08:00 2021
星期 月 日 时间 时区 年
-
getTime();时间戳
System.out.println(date1.getTime());
1634728474370
-
java.sql.Date类 对应着数据库中的日期类型的变量
java.sql.Date date3 = new java.sql.Date(1634728721238L); System.out.println(date3);
结果为:2021-10-20,只输出年月日
-
java.util.Date转换为java.sql.Date对象
利用getTime();方法获取时间戳给java.sql.Date()构造器传参
Date date4 = new Date(); java.sql.Date date5 = new java.sql.Date(date4.getTime()); System.out.println(date5);
-
SimpleDateFormat的使用:对日期和Date类的格式化和解析
-
格式化: 日期—>字符串
SimpleDateFormat sdf1 = new SimpleDateFormat();//使用默认格式的格式化Date date1 = new Date();System.out.println(date1.toString());String format = sdf1.format(date1);System.out.println(format); SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");//使用指定格式的格式化,可以在帮助文档中查看String format1 = sdf3.format(date1);System.out.println(format1);
结果:
Wed Oct 20 20:34:05 GMT+08:00 2021
21-10-20 下午8:34
02021.十月.20 公元 08:34 下午 -
解析: 字符串—>日期 要求字符串符合对应格式,否则会抛出异常
SimpleDateFormat sdf2 = new SimpleDateFormat();//默认格式的解析String str = "21-10-20 下午8:27";Date parse = sdf2.parse(str);System.out.println(parse); SimpleDateFormat sdf4 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");//指定格式的解析String str1 = "02021.十月.20 公元 08:26 下午";Date parse1 = sdf4.parse(str1);System.out.println(parse1);
结果:
Wed Oct 20 20:20:00 GMT+08:00 2021
Wed Oct 20 20:26:00 GMT+08:00 2021
-
练习:
三天打渔两天晒网,从oooo-oo-oo开始,问xxxx-xx-xx是在打渔还是在晒网
思路:总天数除以5取余数,是1,2,3就是打渔,是4,0就是晒网
计算总天数:(endTime - beginTime) / (1000 * 60 * 60 * 24)+1;
public static void main(String[] args)throws ParseException { { //获取开始的时间的时间戳戳 Scanner scanner1 = new Scanner(System.in);//获取键盘输入的时间 System.out.println("请输入开始打渔的时间(格式为:年-月-日):"); String begin = scanner1.nextLine();//获取键盘输入的时间 SimpleDateFormat sdfBegin = new SimpleDateFormat("yyyy-MM-dd"); Date dateBegin = sdfBegin.parse(begin);//指定格式的解析 long beginTime = dateBegin.getTime();//将毫秒值存入 //获取结束时间的时间戳 Scanner scanner = new Scanner(System.in);//获取键盘输入的时间 System.out.println("请输入想要确定是何种状态的时间(格式为:年-月-日):"); String end = scanner.nextLine();//获取键盘输入的时间 SimpleDateFormat sdfEnd = new SimpleDateFormat("yyyy-MM-dd");//指定格式 Date dateEnd = sdfEnd.parse(end);//指定格式的解析 long endTime = dateEnd.getTime();//将毫秒值存入 //计算总天数 long day = (endTime - beginTime) / (1000 * 60 * 60 * 24)+1; System.out.println("从"+begin+"到"+end+"共"+day+"天"); //判断当天是打渔还是晒网 if((day%5)<=3 && (day%5)>=1){ System.out.println(end+"时的状态为:"+"打渔"); }else{ System.out.println(end+"时的状态为:"+"晒网"); } scanner.close(); } }
-
java.util.Canlendar类
@Testpublic void testCalendar(){ //是抽象类 //调用起静态方法getInstance()来实例化 Calendar calendar = Calendar.getInstance(); //常用方法 //get() int days = calendar.get(Calendar.DAY_OF_MONTH); //获取今天是这个月的第几天 System.out.println(days);//21 System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//294 //获取今天是今年的第几天 //set() calendar.set(Calendar.DAY_OF_MONTH,23);//将calendar自身的属性更改 days = calendar.get(Calendar.DAY_OF_MONTH);//获取今天是这个月的第几天 System.out.println(days);//23 System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//296 //获取今天是今年的第几天 //add() calendar.add(Calendar.DAY_OF_MONTH,3);//在之前的基础上加几天()可以为负数 days = calendar.get(Calendar.DAY_OF_MONTH);//获取今天是这个月的第几天 System.out.println(days);//26 System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//299 //getTime():日历类--->Date Date date = calendar.getTime(); System.out.println(date.toString()); //setTime():Date--->日历类 Date date1 = new Date(); calendar.setTime(date1); System.out.println(calendar.get(Calendar.DAY_OF_MONTH));}
JDK8中的新日期时间API
-
Java.time-包含值对象的基础包
Java.time.chrono - 提供对不同的日历系统的访问
Java.time.format-格式化和解析时间和日期
Java.time.temporal-包含底层框架和扩展特性
Java.time.zone-包含时区支持的类
LocalDate、LocalTime、LocalDateTime类的使用
@Testpublic void test1(){ /*LocalDate; LocalTime; LocalDateTime;*/ //now()获取当前日期、时间 LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDate);//2021-10-21 System.out.println(localTime);//20:24:23.059 System.out.println(localDateTime);//2021-10-21T20:24:23.060 //of();设置指定的年月日时分秒 LocalDateTime localDateTime1 = LocalDateTime.of(2000, 1, 1, 13, 23, 23); System.out.println(localDateTime1);//2000-01-01T13:23:23 //getxxx(); System.out.println(localDateTime.getDayOfMonth());//获取当月的第几天: 21 System.out.println(localDateTime.getDayOfWeek());//获取星期几:THURSDAY System.out.println(localDateTime.getDayOfYear());//获取今年的第几天:294 System.out.println(localDateTime.getMonthValue());//获取月份:10 System.out.println(localDateTime.getMinute());//获取分钟:29 //withxxx();设置xxxx相关属性 // 不可变性:不会修改之前变量的日期,只是改变返回值 LocalDate localDate1 = localDate.withDayOfMonth(30); System.out.println(localDate);//2021-10-21 System.out.println(localDate1);//2021-10-30 //plusxxx();增加xxxx相关属性 LocalDateTime localDateTime2 = localDateTime.plusYears(1); System.out.println(localDateTime);//2021-10-21T20:39:30.573 System.out.println(localDateTime2);//2022-10-21T20:39:30.573}
瞬时:Instant,类似于java.utl.Date类
//Instant@Testpublic void test2(){ //now();本初子午线的时间 Instant instant = Instant.now(); System.out.println(instant);//本初子午线的时间 2021-10-21T12:47:00.793Z //instant.atOffset() 偏移量 OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8)); System.out.println(offsetDateTime);//东八区时间 2021-10-21T20:47:00.793+08:00 //instant.toEpochMilli(): 获取时间戳(自1970年1月1日0时0分0秒毫秒数) long milli = instant.toEpochMilli(); System.out.println(milli);//1634820562425 //Instant.ofEpochMilli():通过时间戳获取时间 Instant instant1 = Instant.ofEpochMilli(1634820562425L); System.out.println(instant1);//2021-10-21T12:49:22.425Z}
DateTimeFormatter类,类似于SimpleDateFormat
-
用于格式化与解析日期和时间
@Testpublic void test3(){ //实例化方式一 DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; //格式化 LocalDateTime localDateTime = LocalDateTime.now(); String str1 = formatter.format(localDateTime); System.out.println(localDateTime);//2021-10-21T21:01:25.516 System.out.println(str1);//2021-10-21T21:01:25.516 //解析 TemporalAccessor parse = formatter.parse("2021-10-21T20:59:35.145"); System.out.println(parse.toString());//{},ISO resolved to 2021-10-21T20:59:35.145 //实例化方式二: // 本地化相关的格式,如ofLocalizedDateTime // FormatStyle.SHORT/FormatStyle.LONG/FormatStyle.MEDIUM/FormatStyle.SHORT DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT); //格式化 String str2 = formatter1.format(localDateTime); System.out.println(str2);//21-10-21 下午9:06 //实例化方式三 //自定义格式,如:ofPattern("yyyy-MM-dd hh:mm:ss") DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"); String str3 = formatter2.format(localDateTime); System.out.println(str3);//2021-10-21 09:18:15 TemporalAccessor parse1 = formatter2.parse("2021-10-21 09:18:15"); System.out.println(parse1); //{MinuteOfHour=18, HourOfAmPm=9, NanoOfSecond=0, SecondOfMinute=15, MicroOfSecond=0, MilliOfSecond=0},ISO resolved to 2021-10-21}
-
其他
Java比较器
- java中的对象,正常情况下,只能进行比较 == 或 != ,不能使用>或者<,但是需要进行排序
Comparable接口的使用:自然排序
-
String、包装类等实现了Comparable接口,重写了compareTo()方法,给出了比较两个大小的方式。
public void test1(){ String[] arr = new String[]{"AA","DD","BB","CC","GG"}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); //[AA, BB, CC, DD, GG]}
-
重写compareTo()方法的规则
- 如果当前对象this大于形参对象obj,则返回正整数
- 如果当前对象this小于于形参对象obj,则返回负整数
- 如果当前对象this等于形参对象obj,则返回0
-
对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo()方法,在compareTo(obj) 方法中指明如何排序。
示例:
商品类:
public class Goods implements Comparable{ private String name; private double price; public Goods() { } public Goods(String name, double price) { this.name = name; this.price = price; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public double getPrice() { return this.price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Goods{" + "name='" + name + '\'' + ", price=" +"¥"+ price + '}'; } //指明商品比较大小的方式 @Override public int compareTo(Object o) { if(o instanceof Goods){ //方式一 Goods goods = (Goods)o; //System.out.println(this.name+"\t"+goods.name); if(this.price > goods.price){ return 1; }else if(this.price < goods.price){ return -1; }else{ //return 0; return this.name.compareTo(goods.name); //可以加负号实现由大到小排序 } //方式二 // return Double.compare(this.price,goods.price); } // return 0; throw new RuntimeException("传输的数据类型不一致"); //运行时异常,可以考虑不去处理 }}
测试函数:
public void test2(){ Goods[] arr = new Goods[4]; arr[0] = new Goods("联联",3444); arr[1] = new Goods("华华",2999); arr[2] = new Goods("惠惠",3999); arr[3] = new Goods("苹苹",12899); Arrays.sort(arr); System.out.println(Arrays.toString(arr)); //[Goods{name='华华', price=¥2999.0}, Goods{name='联联', price=¥3444.0}, Goods{name='惠惠', price=¥3999.0}, Goods{name='苹苹', price=¥12899.0}]}
Comparator接口的使用:定制排序
-
背景:当元素的类型没有实现Comparable接口又不方便修改代码
或者实现了Comparable接口的排序规则不适合当前的操作
那么可以考虑使用Comparator的对象来排序
-
重写compare(Object o1,Object o2) 方法,比较o1和o2的大小,若返回正整数,则o1>o2,若返回负整数,则o1<o2,若返回零,则o1==o2。
示例:
-
String的定制排序
public void test3(){ String[] arr = new String[]{"AA","DD","BB","CC","GG"}; 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)); //[GG, DD, CC, BB, AA]}
-
Goods对象的定制排序(Goods类的定义见上面的代码)
public void test4(){ Goods[] arr = new Goods[4]; arr[0] = new Goods("联联",4396); arr[1] = new Goods("联联",3999); arr[2] = new Goods("惠惠",4999); arr[3] = new Goods("苹苹",12899); 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; if(goods1.getName().equals(goods2.getName())){ return Double.compare(goods1.getPrice(),goods2.getPrice()); }else{ return goods1.getName().compareTo(goods2.getName()); } } throw new RuntimeException("输入数据类型不一致"); } }); System.out.println(Arrays.toString(arr)); //[Goods{name='惠惠', price=¥4999.0}, Goods{name='联联', price=¥3999.0}, Goods{name='联联', price=¥4396.0}, Goods{name='苹苹', price=¥12899.0}]}
二者对比:
- Comparable接口的方式一旦确定,保证Comparable接口实现类的对象在任何位置都可以比较大小
- Comparator接口属于临时性的比较
其他
此处引用尚硅谷总结的ppt,B站视频地址:
https://www.bilibili.com/video/BV1Kb411W75N?p=494
System类