字符串类型
字符:简单类型 char,标准格式为单引号
字符串:复合类型String,标准格式双引号
在Java中字符串属于对象,Java提供String类来创建和操作字符串。当对字符串进行频繁修改的时候,需要使用String和StringBuilder类。和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次修改,并且不产生新的未使用的对象
String StringBuffer StringBuilder
String s1 = "ab"+"c";//Java针对+和+=进行了重新定义,在字符串中+表示字符串拼接
String s2 = "abc";
System.out.println(s1==s2);//true 在=复杂类型中==用于比较两个对象的地址是否相同
System.out.println(s1.equals(s2));//true 调用String中的定义方法,用于比较两个字符串的内容是否一致
字符串常量拼接,在方法区的常量池中完成
String s0 = "ab";
String s1 = s0+"c";
String s2 = "abc";
System.out.println(s1.equals(s2));//true
System.out.println(s1==s1);//false
注意:String类是不可改变的,所以你一旦创建了String对象,那它的值就无法改变了。如果修改String中的内容则会导致对象的新建
String类型的拼接是通过StringBuilder类中的append方法来实现的,然后返回toString的结果。是在堆中的新对象
public static void main(String[] args) {
String s1 = "adnaad";// 定义变量,String一般用于字符串类型常量,如果修改内容则会导致对象的新建
// 获取字符串中的字符个数
int len = s1.length();// 字符串中的length是一个方法,数组中的length是一个属性
System.out.println(len);
// 获取指定下标位置上的字符串
for (int i = 0; i < len; i++) {
char cc = s1.charAt(i);
System.out.print(cc + " ");
}
System.out.println();
// 字符串拼接
String s2 = s1 + "123";
System.out.println(s2);
s2 = s1.concat(s2);
System.out.println(s2);
s2 += "ddd";
System.out.println(s2);
// 查询字符串的位置
s1 = "abcdefabdasdfasab";
// 从左向右
int pos1 = s1.indexOf("ab");
System.out.println(pos1);
// 从左向右查询,从指定下标位置开始
pos1 = s1.indexOf("ab", 2);
System.out.println(pos1);
// 从右向左查询
int pos2 = s1.lastIndexOf("ab");
System.out.println(pos2);
pos2 = s1.lastIndexOf("ab", 13);
System.out.println(pos2);
// 获取字符串中的一部分内容:字符串
String s3 = s1.substring(3);// 从指定下标开始到字符串末尾的全部内容
System.out.println(s3);
s3 = s1.substring(3, 6);// 从指定下标开始到指定下标结束,这两个位置之间的内容,含左不含右
System.out.println(s3);
// 字符串的替换
s1 = "abcdefghi";
s2 = s1.replace("ab", "qwer");// 字符串中指定的字符串替换为新的字符串
System.out.println(s2);
// 使用指定的字符将字符串分割为字符串数组【实际上是正则式】
s1 = "sa,sa,sa,sa,sa,sa,sadf,df,dfr,gs,d";
String[] arr = s1.split(",");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
StringBuilder 和StringBuffer的基本用法
public static void main(String[] args) {
// String一般用于常量字符串,如果需要频繁修改则可以使用StringBuilder和StringBuffer
StringBuilder sb1 = new StringBuilder();
StringBuffer sb2 = new StringBuffer();
// 拼接字符串
sb2.append("123");// 在字符串的末尾拼接
System.out.println(sb2);
sb2.insert(1, "ret");// 在指定位置的下标插入字符串
System.out.println(sb2);
sb2.delete(1, 3);// 删除指定位置上的内容,star=1 end=3
System.out.println(sb2);
sb2.deleteCharAt(1);// 删除指定下标的字符
System.out.println(sb2);
sb2.replace(1, 2, "新的内容");// 将制=指定下标的内容替换为新的内容
System.out.println(sb2);
// 反转字符串
sb2.reverse();
System.out.println(sb2);
// 获取字符串个数
int len = sb2.length();
System.out.println(len);
// 插找位置
int pos = sb2.indexOf("容内");
System.out.println(pos);
// 其余方法基本上和String一致
String s1 = sb2.substring(pos);
System.out.println(s1);
}
数据类型转换
String–Integer 或者其他类型,基本语法:包装类名称.parseXXX
String s11 = "123";
int kk = Integer.parseInt(s11);// 返回int
System.out.println(kk + 1);
int k2 = Integer.valueOf(s1);// 返回值integer,自动拆箱
System.out.println(k2 + 10);
Integer或者简单类型或者其他数据类型—String
int kk = 123;
String ss = ""+kk;//自动转换
特殊用法:String 类使用静态方法format()返回一个String 对象,是用来创建可复用的格式化字符串最常见的格式符号:浮点数%f、整型%d、字符串%s、特殊符号不用记忆临时查
public static void main(String[] args) {
String s1 = "这是一个用于测试的模板,其中整数值为%d八进制为%o";
System.out.println(String.format(s1, 123, 123));// 替代规则为位置对应,具体的数据应该和特殊符号%x对应
String ss = null;
// 字符串的判空处理
// trim方法的含义是去掉字符串前后两端的空格
if (ss == null || ss.trim().length() < 1) {
System.out.println("字符串的内容为空");
}
String ss1 = null;
// 如果使用普通方法进行判断ss.equals("bbb")时会出现异常中断,使用objects.equals可以避免空指针异常
if (Objects.equals(ss1, "bbb")) {
System.out.println("字符串内容为bbb");
}
}
可变与不可变
- String类中使用字符数组保存字符串,因为有final修饰符,所以可以知道string对象是不可变的。 private final char value[];
- StringBuilder与StringBuffer都是继承AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,克制这两种对象都是可变的。char [] value;
是否多线程安全
-
String中的对象是不可变的,也就可以理解为常量,显然线程安全
-
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作。如expandCapacity、append、insert、indexOf等公共方法
-
StringBuffer对方法加了同步锁或者对调用方法加了同步锁,所以线程是安全的。StringBuilder并没有对方法进行加同步锁,所以非线程是安全的。
StringBuilder 和StringBuffer共同点
-
StringBuilder与StringBuffer公共父类AbstractStringBuilder抽象类。抽象类与接口的其中一个区别是:抽象类可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义
-
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)只是StringBuffer会在方法上家synchronize关键字,进行同步
如果程序不是多线程的,那么StringBuilder效率高于StringBuffer
包装类
Java并不是纯面向对象的语言,Java语言是一个面向对象的语言,但是Java中的基本数据类型却不是面向对象的,但是我们在实际使用中经常将基本数据类型转换成对象,为了使用Java封装好的方法,以便于操作。例如获取int的最大值或者最小值Integer.MAX_VALUE或者Integer.MIN_VALUE
java中支持自动装拆箱操作,可以自动在简单类型和包装类型之间进行转换
8中简单数据类型及其包装类
-
byte—Byte short–Short int–Integer long–Long
-
float–Float double----Double
-
boolean–Boolean
-
char–Character
int kk = 123;
Integer k2 = kk;//自动装箱
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(k2.toString());//将Integer转化为String类型
String s1= Integer.toBinaryString(123);//十进制转化为二进制
String s2 = Integer.toOctalString(123);//十进制转化为八进制
String s3 = Integer.toHexString(123);//十进制转化为十六进制
System.out.println(s1+" "+s2+" "+s3);
int k3 = k2;//自动拆箱
日期类
java.util包提供了Date类来封装当前的日期和时间
-
Date:getTime()、setTime()
Date now = new Date();// 构建一个日期对象,默认封装系统当前时 System.out.println(now); // 指定年月构建日期对象,需要注意参数规则 Date d1 = new Date(2000 - 1900, 2 - 1, 3);// 参数分别是year,month,date,注意传入年-1900,月份-1 System.out.println(d1); // 日期类型对象中并不是直接封装年月日具体值,而是存储了一个1970-1-1 0:0:0到指定日期的毫秒值 long l1 = now.getTime();// 获取毫秒值 System.out.println(l1); // 日期中的减法 now-d1; long s1 = now.getTime() - d1.getTime(); // 两个日期之间的天数差 System.out.println(s1 / 1000 / 60 / 60 / 24); // 日期对象中提供了获取年月如分秒的方法 System.out.println(now.getYear());// 年份 System.out.println(now.getMonth());// 月份 System.out.println(now.getDate());// 日期 System.out.println(now.getDay());// 星期 System.out.println(now.getHours());// 小时 System.out.println(now.getMinutes());// 分钟 System.out.println(now.getSeconds());// 秒
-
DateFormat:getInstance()、getDateInstance()、getDateTimeInstance()、getTimeInstance()
-
SimpleDateFormate:formate(Date)、parse(String s)
public static void main(String[] args) {
Date now = new Date();
DateFormat df = new SimpleDateFormat("yyyy年mm月d日 E hh点mm分ss秒");
// 自定义日期格式
String s1 = df.format(now);
System.out.println(s1);// 2021年08月9日 星期四 05点08分30秒
// 将字符串按照指定的格式解析为日期类型
try {
// 可能出现异常,必须进行处理
Date dd = df.parse(s1);
System.out.println(dd);
} catch (ParseException e) {
e.printStackTrace();
}
}
// 根据现在的时间计算
Calendar now = Calendar.getInstance();
now.add(Calendar.YEAR, 1);// 现在时间是一年后
now.add(Calendar.YEAR, -1);// 现在时间是一年前
// 根据某个特定时间 date(Date 型)计算
Calendar specialDate = Calendar.getInstance();
specialDate.setTime(new Date());// 注意此处将specialDate的值改为特定日期
specialDate.add(Calendar.YEAR, 1);
specialDate.add(Calendar.YEAR, -1);