String
String字符串,使用""引用来表示
- 1、String声明为final,不可 被继承
- 2、实现了Serializable接口,表示字符串是支持序列化的
- 3、实现了Comparable接口,表示可以比较大小
- 4、内部定义了final char value[],用于存储字符串数据
- 5、String:代表不可变的字符序列。简称不可变性
当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
当对现有的字符串进行连接操作时,也需要重写指定内存区域赋值,不能使用原有的value进行赋值
当调用String的replace()方法修改指定字符或字符串时,也需要重写指定内存区域赋值,不能使用原有的value进行赋值
- 6、通过字面量方式给一个字符串赋值,此时的字符串值声明在字符串常量池中
- 7、字符串常量池不会存储相同内容的字符串的。
package com.linfeng.java;
import org.junit.Test;
public class StringTest {
/*
* String字符串,使用""引用来表示
* 1、String声明为final,不可 被继承
* 2、实现了Serializable接口,表示字符串是支持序列化的
* 3、实现了Comparable接口,表示可以比较大小
* 4、内部定义了final char value[],用于存储字符串数据
* 5、String:代表不可变的字符序列。简称不可变性
* 当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值
* 当对现有的字符串进行连接操作时,也需要重写指定内存区域赋值,不能使用原有的value进行赋值
* 当调用String的replace()方法修改指定字符或字符串时,也需要重写指定内存区域赋值,不能使用原有的value进行赋值
* 6、通过字面量方式给一个字符串赋值,此时的字符串值声明在字符串常量池中
* 7、字符串常量池不会存储相同内容的字符串的。
* */
@Test
public void test1(){
String s1 = "abc";//字面量的定义方式
String s2 = "abc";
// s1="hello";
System.out.println(s1 == s2);
System.out.println(s1);
System.out.println(s2);
System.out.println("*************");
String s3 = "hel";
s3 += "lo";
System.out.println(s3);//hello
System.out.println("*************");
String s4 = "abc";
String s5 = s4.replace('a', 'm');
System.out.println(s4);//abc
System.out.println(s5);//mbc
}
}
面试题:String s=new String(“abc”)方式创建对象,在内存中创建了几个对象?
两个,一个是堆空间中new的结构,另一个是char[]对应常量池中的数据“abc”
String s1="leet";
String s2="Code";
String s3="leetCode";
String s4="leet"+"Code";
String s5=s1+"Code";
String s6="leet"+s2;
String s7=s1+s2;
String s8=s5.intern();//返回值得到的s8使用的是常量池中的字符串
s3==s4;//true,都是在常量池中
s3==s5;//false,只要有变量参与,都在堆中
s3==s6;//false
s3==s7;//false
结论:
- 常量与常量的拼接结果在常量池,且常量池中不会存在相同容量的常量
- 只要其中有一个是变量,结果就在堆中
- 如果拼接的结果调用intern(方法),返回值就在常量池中
String中的方法
int length();//返回字符串长度
char charAt(int index);//返回某索引处的字符
boolean isEmpty();//判断是否为空字符串
String toLowerCase();//转小写
String toUpperCase();//转大写,字符串本身不变,需要新建字符串接收
String trim();//去除首尾空格
boolean equals();
boolean equalsIgnoreCase();//和equals类似,忽略大小写
int CompareTo();//比较两个字符串的大小,负数则当前字符串小
String subString(int beginIndex);//返回一个新的字符串,他是此字符串的从beginIndex开始截取到最后的一个子字符串
String subString(int beginIndex,int endIndex);//返回一个新的字符串,他是此字符串的从beginIndex开始截取endIndex(不包含)的一个子字符串
boolean endsWith();//是否以指定的字符串结束
boolean startsWith(String prefix,int toffset);//指定索引位置开始的子字符串是否以指定前缀开始
String concat(String str)//将指定字符串连接到此字符串结尾。等价于+
public boolean startsWith(String prefix):判断当前字符串是否以prefix开始。
public boolean endsWith(String suffix):判断当前字符串是否以suffix结束。
String与基本数据类型、包装类的转换
String—>基本数据类型、包装类:调用包装类的静态方法:parseXxx(str)
package com.linfeng.java;
import org.junit.Test;
public class test2 {
@Test
public void test(){
String s1 = "123";
//Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型。
int i = Integer.parseInt(s1);
System.out.println(i);
//类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应
//的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型
byte b = Byte.parseByte(s1);
System.out.println(b);
}
}
@Test
public void test2(){
int i = 1234;
String s = String.valueOf(i);
System.out.println(s);
}
String与字符数组转换
@Test
//String与char[]之间转换
// String ---->char[]:调用String的toCharArray()
//char-------->String:调用String的构造器
public void t1(){
String str1 = "abc123";
char[] chars = str1.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}
String与字节数组转换
package com.linfeng.java;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class test2 {
@Test
public void test(){
String s1 = "123";
//Integer包装类的public static int parseInt(String s):可以将由“数字”字符组成的字符串转换为整型。
int i = Integer.parseInt(s1);
System.out.println(i);
//类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应
//的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型
byte b = Byte.parseByte(s1);
System.out.println(b);
}
@Test
public void test2(){
int i = 1234;
String s = String.valueOf(i);
System.out.println(s);
}
@Test
//String与char[]之间转换
// String ---->char[]:调用String的toCharArray()
//char-------->String:调用String的构造器
public void t1(){
String str1 = "abc123";
char[] chars = str1.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
}
@Test
public void t2() throws UnsupportedEncodingException {
// String s1="abc123";
String s2 = "abc中国";
//String------>byte[]:调用Spring的getBytes()
byte[] bytes = s2.getBytes();//使用默认字符集转换
System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51]
byte[] gbks = s2.getBytes("gbk");//使用jdk字符集编码
System.out.println(Arrays.toString(gbks));//[97, 98, 99, 49, 50, 51]
System.out.println("*************************");
//byte[]----->String:调用String的构造器
String s = new String(bytes);//使用默认的字符集解码
System.out.println(s);
String s3 = new String(gbks);
System.out.println(s3);//出现乱码
String s4 = new String(gbks, "gbk");//使用指定的gbk进行编码
System.out.println(s4);//无乱码
}
}
字符串相关的类:StringBuffer与StringBuilder
StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且
提供相关功能的方法也一样
面试题:对比String、StringBuffer、StringBuilder
- String(JDK1.0):不可变字符序列
- StringBuffer(JDK1.0):可变字符序列、效率低、线程安全
- StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全
注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder
会改变其值。
StringBuffer类的常用方法:
练习:
@Test
public void t3(){
String a = "123";
String b = "123";
String c = new String("123");
String d = new String("123");
System.out.println(a.equals(b));//true
System.out.println(a==b);//t
System.out.println(c.equals(d));//t
System.out.println(c==d);//f
System.out.println(a.equals(c));//t
System.out.println(a==c);//f
}
JDK8之前日期时间API
- java.lang.System类
- java.util.Date类
- java.text.SimpleDateFormat类
- java.util.Calendar(日历)类
@Test
public void t1(){
//1、system类中的currentTimeMillis
long l = System.currentTimeMillis();//称为时间戳
System.out.println(l);//来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
}
@Test
public void t2(){
//构造器1;Date():创建一个对应当前时间的Date对象
Date date = new Date();
System.out.println(date.toString());//Wed May 04 14:11:47 CST 2022
System.out.println(date.getTime());//1651644707060
//构造器2:创建指定时间戳的date对象
Date date1 = new Date(6516447070601L);
System.out.println(date1.toString());
//java.sql.date对应着数据库中的日期类型的变量
//创建java.sql.date对象
java.sql.Date date2 = new java.sql.Date(6516447070601L);
System.out.println(date2);//2176-07-01
//如何将util.Date转化为sql.Date
Date date3 = new Date();
// java.sql.Date date4 = (java.sql.Date) date3;//报错
java.sql.Date date4 = new java.sql.Date(date3.getTime());
}
@Test
public void t1() throws ParseException {
/*SimpleDateFormat()两个操作
1、格式化:日期----->字符串
2、解析:字符串----->日期
*/
SimpleDateFormat s1 = new SimpleDateFormat();//实例化
//1、格式化
Date date = new Date();
System.out.println(date.toString());//Wed May 04 14:37:02 CST 2022
String s = s1.format(date);
System.out.println(s);//22-5-4 下午2:37
//2、解析
String s2 = "22-3-4 下午2:37";//注意格式
Date parse = s1.parse(s2);
System.out.println(parse);//Fri Mar 04 14:37:00 CST 2022
System.out.println("*******************");
Date date1 = new Date();
SimpleDateFormat st = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String s3 = st.format(date1);
System.out.println(s3);//2022-05-04 02:53:19
}
@Test
public void t3(){
//Calendar是一个抽象基类
//实例化
// 方式1:调用它的子类GregorianCalendar的构造器
//方式2:使用Calendar.getInstance()方法
Calendar instance = Calendar.getInstance();
//get()
Date date = new Date();
int i = instance.get(DAY_OF_MONTH);
System.out.println(i);//4
System.out.println(instance.get(Calendar.DAY_OF_YEAR));//124
//set()
instance.set(DAY_OF_MONTH,22);
int i1 = instance.get(DAY_OF_MONTH);
System.out.println(i1);//22
//add
instance.add(DAY_OF_MONTH,2);
int i2 = instance.get(DAY_OF_MONTH);
System.out.println(i2);//24
// gettime() 日历类---->Date
Date date1 = instance.getTime();
System.out.println(date1);//Tue May 24 16:51:38 CST 2022
//settime() Date---->日历类
Date date2 = new Date();
instance.setTime(date2);
int i3 = instance.get(DAY_OF_MONTH);
System.out.println(i3);//4
}
JDK8中新日期时间API
LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例
是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。
它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区
相关的信息。
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。
注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示
法,也就是公历。
package com.linfeng.java;
import org.junit.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class TimeNow {
@Test
public void t1(){
//实例化1、now():获取当前日期、时间、日期+时间
LocalDate now = LocalDate.now();
LocalTime now1 = LocalTime.now();
LocalDateTime now2 = LocalDateTime.now();
System.out.println(now);//2022-05-04
System.out.println(now1);//19:49:34.361
System.out.println(now2);//2022-05-04T19:49:34.361
//实例化2、of():设置指定日期,没有偏移量
LocalDate date = LocalDate.of(2022, 5, 4);
System.out.println(date);//2022-05-04
System.out.println("************************************");
//getXxx()
System.out.println(now2.getDayOfMonth());//当月第四天
System.out.println(now2.getDayOfWeek());//星期三
System.out.println(now2.getMonth());//5月
System.out.println(now2.getMonthValue());//5
System.out.println(now2.getMinute());//第56分钟
System.out.println("**************************");
//local体现不可变性
//withXxx:设置相关的属性
LocalDateTime time = now2.withDayOfMonth(22);
System.out.println(now2);//2022-05-04T20:01:22.272
System.out.println(time);//2022-05-22T20:01:22.272
System.out.println("**************");
//增加
LocalDateTime months = now2.plusMonths(3);
System.out.println(now2);//2022-05-04T20:07:12.312
System.out.println(months);//2022-08-04T20:07:12.312
System.out.println("**************");
//减
LocalDateTime d1 = now2.minusDays(3);
System.out.println(now2);//2022-05-04T20:07:12.312
System.out.println(d1);//2022-05-01T20:08:59.339
}
}
package com.linfeng.java;
import org.junit.Test;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class TimeNow2 {
@Test
public void t2(){
//实例化1
Instant now = Instant.now();
System.out.println(now);//2022-05-04T12:39:35.926Z,按照本初子午线的时间
//实例化2
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);//2022-05-04T22:45:25.977+08:00
//获取自1970年1月1日0时0分0秒(UTC)开始的毫秒数。
long l = now.toEpochMilli();
System.out.println(l);//1651675728284
//给定毫秒数,获取instant实例
Instant instant = now.ofEpochMilli(1651675728284L);
System.out.println(instant);//2022-05-04T14:48:48.284Z
}
}
@Test
public void t4(){
//预定义的标准格式。如:
//ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化:日期----->字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str = formatter.format(localDateTime);
System.out.println(localDateTime);//2022-05-05T10:11:55.606
System.out.println(str);//2022-05-05T10:11:55.606
//解析
TemporalAccessor parse = formatter.parse("2022-05-05T10:11:55.606");
System.out.println(parse);//{},ISO resolved to 2022-05-05T10:11:55.606
//本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
//FormatStyle.LONG FormatStyle.MEDIUM FormatStyle.SHORT 适用于localDatetime
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
//格式化
String str2 = formatter1.format(localDateTime);
System.out.println(str2);//22-5-5 上午10:21
//自定义方式 如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//格式化
String s = formatter2.format(localDateTime);
System.out.println(s);//2022-05-05 10:26:25
//解析
TemporalAccessor parse1 = formatter2.parse("2022-05-05 10:26:25");
System.out.println(parse1);//{MilliOfSecond=0, MinuteOfHour=26, HourOfAmPm=10, SecondOfMinute=25, NanoOfSecond=0, MicroOfSecond=0},ISO resolved to 2022-05-05
}