JavaSE:Java常用类
字符串相关的类
String类
String 类:代表字符串。java程序中的所有字符串字面值(如:“abc”)都作为此类的实例实现。
String是一个final 类,代表不可变的字符序列。简称:不可变性。
String :
-
实现了serialzable接口:表示字符串是支持序列化的
-
实现了Comparable 接口:表示String可以比较大小
String内部定义了 final char[] value ,String对象的字符内容是存储在这个**字符数组value[]**中的。
说明:
- 通过字面量的方式给一个字符串赋值,此时的字符串值声明在字符串常量池中。
- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value 进行赋值。
- 当调用String的replace()方法修改字符或字符串时,也必须重新指定内存区域赋值,不能使用原有的value 进行赋值。
- 字符串常量池中是不会存储相同内容的字符串的。
不可变性:
- 通过字面量的方式给一个字符串赋值,此时的字符串值声明在字符串常量池中。
- 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value 进行赋值。
- 当调用String的replace()方法修改字符或字符串时,也必须重新指定内存区域赋值,不能使用原有的value 进行赋值。
- 字符串常量池中是不会存储相同内容的字符串的。
不同实例化方式的对比
方式一:通过字面量定义的方式
方式二:通过new + 构造器的方式
public void Test(){
//通过字面量定义的方式:此时的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
System.out.println("*********************");
String ss1 = "javaEE";
String ss2 = "hadoop";
String ss3 = "javaEEhadoop";
String ss4 = "javaEE" + "hadoop";
String ss5 = s1 + "hadoop";
String ss6 = "javaEE" + s2;
String ss7 = s1 + s2;
System.out.println(ss3 == ss4);//true
System.out.println(ss3 == ss5);//false
System.out.println(ss3 == ss6);//false
System.out.println(ss3 == ss7);//false
System.out.println(ss5 == ss6);//false
System.out.println(ss5 == ss7);//false
System.out.println(ss6 == ss7);//false
String ss8 = s5.intern();
System.out.println(ss3 == ss8);//true
}
-
通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法去中的字符串常量池中
-
通过new + 构造器的方式:此时s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值。
-
常量与常量的拼接,结果再常量池中,且常量池中不会存在相同内容那个 常量。
-
只要其中有一个是变量,结果就再堆空间中
-
如果拼接的结果调用intern方法,返回值就在常量池中
StringBuffer 类和 StringBuilder 类
- 使用 StringBuffer 的空参构造器创建对象,底层创建的是一个长度为16的字符型数组。
- 使用带参构造器创建对象,底层创建的则是str.length() + 16 的长度的字符型数组。
- 扩容问题:如果要添加的数据底层数组盛不下,那就要考虑扩容底层的数组。默认情况下扩容为原来的2倍再加2,同时将原有的数组中的元素复制到新的数组中。如果扩容为原本的2倍+2仍然不够的话,将使用要添加数据的长度为数组长度。
- StringBuilder为JDK1.5时新添加,相比于StringBuffer,StringBuilder底层没有使用Synchronized修饰,也就是说它是线程不安全的,因此,StringBuilder的效率也比StringBuffer的效率高。
String、StringBuffer和StringBulider 三者的异同
- String:不可变的字符序列;底层使用char[] 进行存储。
- StringBuffer:可变的字符序列;线程安全的,效率低底层使用char[] 进行存储。
- StringBulider:可变的字符序列;线程不安全,效率高;jdk5.0新增,底层使用char[] 进行存储。
JDK 8 前的日期API
System类中currentTimeMillis();
返回一个double类型的变量,值为当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。成为时间戳。
public static void main(String[] args) {
//system类中的currentTimeMillis()静态方法,获取当前时间到1970年1月1日0时0分0秒的毫秒数
//也称为时间戳
long timeMillis = System.currentTimeMillis();
System.out.println(timeMillis);
}
java.util.Date 和子类 java.sql.Date
java API提供了两个Date类: java.util.Date 以及其子类 java.sql.Date。
public static void main(String[] args) {
//实例化 java.util.Date
//方式一:获取当前时间
Date date = new Date();
System.out.println(date);// Fri Oct 02 11:29:40 CST 2020
//方式二: 获取指定时间戳的日期
Date date1 = new Date(16043425244L);
System.out.println(date1);// Mon Jul 06 00:30:25 CST 1970
//调用getTime方法获取时间戳
long time = date.getTime();
System.out.println(time);//1601609575244
//实例化java.sql.Date
java.sql.Date date2 = new java.sql.Date(time);
System.out.println(date2);//2020-10-02
}
SimpleDateFormat
simpleDateFormat 用于对Date类的格式化和解析
public static void main(String[] args) throws ParseException {
//simpleDateFormat 用于对Date类的格式化和解析
//实例化SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat();
Date date = new Date();
System.out.println(date);//Fri Oct 02 11:41:15 CST 2020
String s = sdf.format(date);//格式化:将Date类型转换为String类
System.out.println(s);//20-10-2 上午11:41 ---- 若不指定格式化格式,此为格式化的默认格式。
Date date1 = sdf.parse("98-05-14 上午11:41");//解析:将相应格式的String类转换为Date
System.out.println(date1);//Thu May 14 11:41:00 CST 1998
//创建指定格式的simpleDateFormat 对象。
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");
String format = sdf1.format(new Date());//格式化
System.out.println("指定格式格式化:" + format);//2020-10-02 12-13-50
//解析
Date date2 = sdf1.parse("2008-7-29 16-25-31");
System.out.println("指定格式解析:" + date2);//Tue Jul 29 16:25:31 CST 2008
}
运行结果:
Calendar
public static void main(String[] args) {
//实例化:calendar是一个抽象类,但有一个静态方法,一般使用此方法直接获取Calendar对象
Calendar instance = Calendar.getInstance();
System.out.println(instance.getClass());//class java.util.GregorianCalendar
//也可以直接new其子类GregorianCalendar 获取对象
GregorianCalendar gc = new GregorianCalendar();
//常用方法
//get()
int dayOfYear = instance.get(Calendar.DAY_OF_YEAR);//获取今天为今年的第几天
int dayOfWeek = instance.get(Calendar.DAY_OF_WEEK);//获取今天为这周的第几天
int dayOfWeekInMonth = instance.get(Calendar.DAY_OF_WEEK_IN_MONTH);//获取本周是这个月的第几天
//set 此方法返回值为void,修改是再原本数据上修改,并非生成另外一个对象
instance.set(Calendar.DAY_OF_YEAR,250);//instance.DAY_OF_YEAR 设置为本年的第250天
System.out.println(instance.get(Calendar.DAY_OF_YEAR));//250
//add 返回值为void
instance.add(Calendar.DAY_OF_YEAR,30);
System.out.println(instance.get(Calendar.DAY_OF_YEAR));//280
//getTime Calendar --> Date
Date date = instance.getTime();
System.out.println(date);
//setTime Date --> Calendar
instance.setTime(new Date());
}
JDK 8 中新日期时间API
LocalDate、LocalTime、LocalDateTime
public static void main(String[] args) {
//LocalDate、LocalTime、LocalDateTime
//now 获取现在的的日期/时间/日期和时间
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);//2020-10-02
System.out.println(localTime);//12:49:05.972
System.out.println(localDateTime);//2020-10-02T12:49:05.972
//of 设置指定年月日时分秒,且没有偏移量
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 10, 1, 12, 0, 0);
System.out.println(localDateTime1);//2020-10-01T12:00
//常用方法
//getXxx
int dayOfYear = localDateTime1.getDayOfYear();
int dayOfMonth = localDateTime1.getDayOfMonth();
int monthValue = localDateTime1.getMonthValue();
Month month = localDateTime1.getMonth();
System.out.println(dayOfYear);//275
System.out.println(dayOfMonth);//1
System.out.println(monthValue);//10
System.out.println(month);//OCTOBER
//withXxx
LocalDateTime localDateTime2 = localDateTime1.withDayOfYear(250);
LocalDateTime localDateTime3 = localDateTime1.withDayOfMonth(2);
LocalDateTime localDateTime4 = localDateTime1.withMonth(5);
System.out.println(localDateTime2.getDayOfYear());
System.out.println(localDateTime3.getDayOfMonth());
System.out.println(localDateTime4.getMonth());
//plusXxx
LocalDateTime localDateTime5 = localDateTime4.plusMonths(3);
System.out.println(localDateTime5.getMonthValue());
//minusXxx
LocalDateTime localDateTime6 = localDateTime5.minusMonths(4);
System.out.println(localDateTime6.getMonthValue());
}
DateTimeFormatter
对 LocalDate、LocalTime、LocalDateTime 的格式化和解析,和SimpleDateFormat相似
public static void main(String[] args) {
//方式一:预定义的标准格式:如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime localDateTime = LocalDateTime.now();
String s = formatter.format(localDateTime);
System.out.println(localDateTime);//2020-10-02T16:03:03.315
System.out.println(s);//2020-10-02T16:03:03.315
TemporalAccessor parse = formatter.parse("2020-10-02T16:03:03.315");
System.out.println(parse);//{},ISO resolved to 2020-10-02T16:03:03.315
//方式二
//本地相关的格式:如:ofLocalizedDateTime()
//FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
String s1 = formatter1.format(localDateTime);
System.out.println(s1);//2020年10月2日 下午04时09分07秒
TemporalAccessor parse1 = formatter1.parse("2020年10月2日 下午04时09分07秒");
System.out.println(parse1);//{},ISO resolved to 2020-10-02T16:09:07
//本地相关的格式:如:ofLocalizedDate()
//FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDate
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
String s2 = formatter2.format(localDateTime);
System.out.println(s2);//2020年10月2日 星期五
TemporalAccessor parse2 = formatter2.parse("2020年10月2日 星期五");
System.out.println(parse2);//{},ISO resolved to 2020-10-02
//方式三:自定义格式。如:ofPatten("yyyy-MM-dd hh-mm-dd");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-dd");
String s3 = formatter3.format(localDateTime);
System.out.println(s3);//2020-10-02 04-26-02
TemporalAccessor parse3 = formatter3.parse("2020-10-02 04-26-02");
System.out.println(parse3);//{HourOfAmPm=4, MinuteOfHour=26},ISO resolved to 2020-10-02
}
Java比较器
说明:java 中的对象,正常情况下,只能进行比较: == 或 != 。不能使用 > 或 < 的,但是开发场景中,我们需要对多个对象进行排序,也就是说,需要对对象进行排序。
comparable 的使用:自然排序
- 像String、包装类等实现了Comparable接口,重写了compareTo()方法,给出了比较两个对象大小的方法
- 像String、包装类重写compareTo()方法以后,进行了从小到大的排序。
- 重写compareTo()的规则:
- 如果当前对象this大于形参对象obj,则返回正整数。
- 如果当前对象this小于形参对象obj,则返回负整数。
- 如果当前对象this等于形参对象obj,则返回0。
- 对于自定义类来说,如果需要排序,可以让自定义类实现Comparable接口,重写compareTo()方法。在compareTo()方法中指定如何排序
自定义类
public class Goods implements Comparable{
private String GoodsName;
private int price;
public Goods() {
}
public Goods(String goodsName, int price) {
GoodsName = goodsName;
this.price = price;
}
public String getGoodsName() {
return GoodsName;
}
public void setGoodsName(String goodsName) {
GoodsName = goodsName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
//按照价格从低到高排序
@Override
public int compareTo(Object o) {
if (o instanceof Goods){
Goods goods = (Goods) o;
if (this.price > goods.price){
return 1;
}else if (this.price < goods.price){
return -1;
}else{
return 0;
}
}
throw new RuntimeException("类型数据不匹配!");
}
@Override
public String toString() {
return "Goods{" +
"GoodsName='" + GoodsName + '\'' +
", price=" + price +
'}';
}
}
使用比较器,进行排序
public static void main(String[] args) {
Goods[] goods = new Goods[5];
goods[0] = new Goods("ASUS",2060);
goods[1] = new Goods("Lenovo",2020);
goods[2] = new Goods("Dell",1998);
goods[3] = new Goods("Mac",3090);
goods[4] = new Goods("HP",2080);
//遍历
for(Goods goods1:goods){
System.out.println(goods1);
}
Arrays.sort(goods);
System.out.println("*********** 自然排序后 *************");
//按照价格从小到大排序
//遍历
for(Goods goods1:goods){
System.out.println(goods1);
}
}
打印结果
comparator 的使用:自定义排序
public static void main(String[] args) {
Goods[] goods = new Goods[5];
goods[0] = new Goods("ASUS",2060);
goods[1] = new Goods("Lenovo",2020);
goods[2] = new Goods("Dell",1998);
goods[3] = new Goods("Mac",3090);
goods[4] = new Goods("HP",2080);
//遍历
for(Goods goods1:goods){
System.out.println(goods1);
}
System.out.println("*********** 定制排序后 *************");
//按照价格从大到小排序
Arrays.sort(goods, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
if (o1.getPrice() > o2.getPrice()){
return -1;
}else if (o1.getPrice() < o2.getPrice()){
return 1;
}else{
return 0;
}
}
});
//遍历
for(Goods goods1:goods){
System.out.println(goods1);
}
}
运行结果
comparable 和 comparator 接口对比
- Comparable 接口的方式一旦定义,保证Comparable接口实现类的对象再任何位置都可以比较大小。
- Comparator接口属于临时性的比较。