Java String知识复习及补充和包装类
Java String知识复习及补充和包装类
Java String知识复习及补充和包装类
- 1. String类
- 1.1 String API复习
- 1.2 正则表达式
- 1.3 StringBuffer 和 StringBuilder
- 1.4 String, StringBuffer,StringBuilder的区别
- 2. 包装类
1. String类
1.1 String API复习
String: 底层实现是final的字节数组 byte[]回顾: 不可变的字符序列new String() -> ""new String("hi") -> "hi"new String(char[] {'h','e'}) -> henew String(byte[] {97, 65}) -> a AString str = "he";String str1 = "h" + "e";str == str1 -> true -> 字符串常量池int length() 输出字符串的长度int indexOf(String) 获取字符串中指定字符第一次出现的位置String substring(int start, int end) 截取字符串char charAt(int index) 获取对应下标的字符boolean startsWith(String) 判断是否以xx开头boolean endsWith(String) 判断是否以xx结尾String trim() 清除字符串两边的空格boolean equals(String) 比较2个字符串boolean equalsIgnoreCase(String) 比较2个字符串,无视大小写String toUpperCase() 将字符串全部变成大写String toLowerCase() 将字符串全部变成小写String replace(String old, String new) 替换指定字符串
1.2 正则表达式
实际开发中,经常需要用到对字符串数据进行一些复杂的匹配、查找、替换等操作。通过正则表达式,可以方便的实现字符串的复杂操作。
正则表达式是一串特定字符,组成一个规则字符串。这个规则字符串是描述文本规则的工具。正则表达式就是记录文本规则的代码。
代码演示:
package StringDemo;import java.util.Arrays;public class Demo01 {public static void main(String[] args) {//判断字符串是否合法String str = "ssss.-_dsadsa@xxx.com";// \w{6,18}@\w{2,8}(\.\w{2,6})+//String regex = "^\\w{6,18}@\\w{2,8}(\\.\\w{2,6})+$";String regex = "^[a-zA-Z0-9_.-]+@([a-zA-Z0-9]+\\.)+[a-zA-Z0-9]{2,4}$";boolean m = str.matches(regex);System.out.println(m);//按照空格拆分String str1 = "aa cc ww qq ww rr kk ll";acString[] regex1 = str1.split("[\\s]+");System.out.println(Arrays.toString(regex1));String str2 = "100+200-300===0";regex1 = str2.split("[\\+\\-=]+");System.out.println(Arrays.toString(regex1));//替换指定字符String str3 = "笨蛋!笨蛋!笨蛋!";str3 = str3.replaceAll("笨蛋", "**");System.out.println(str3);}
}
相关的的API:
1.boolean matches(String regex) 测试两个字符串区域是否相等。
2.String replaceAll(String regex, String newStr) 用给定的替字符串替换此字符串的每个子字符串。
3.String[] split(String regex) 将字符串切割
1.3 StringBuffer 和 StringBuilder
String 是不可变的, 所以频繁的字符串拼接非常消耗时间/内存
解决方案: 提供了新的类, 可变字符串 StringBuffer和StringBuilder
StringBuffer : 线程安全的
StringBuilder: 效率高
StringBuffer和StringBuilder的使用方法基本相似。
构造方法:StringBuilder sb = new StringBuilder() -> ""String str = sb.toString()StringBuilder sb = new StringBuilder(String)
常用API: - 返回值都是this, 在对象本身进行修改append(Object o) -> 在字符串末尾追加新的内容delete(int start, int end)replace(int start, int end, String replacement)insert(int index, String str)reverse()
public class Demo05StringBuilder {public static void main(String[] args) {//可变字符串 sb 返回值都是this,在对象本身进行修改StringBuilder sb = new StringBuilder("kinoko");///字符串拼接//在字符串末尾追加System.out.println(sb.append("sa"));System.out.println(sb.append("ka"));//指定位置插入System.out.println(sb.insert(3, "ur"));//将start和end之间的字符串替换System.out.println(sb.replace(0, 4, "T-T"));//删除start和end之间的字符串System.out.println(sb.delete(0, 3));//字符串反转System.out.println(sb.reverse());//将StringBuilder转换成不可变的String对象System.out.println(sb.toString());}
}
1.4 String, StringBuffer,StringBuilder的区别
java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。
①.可变与不可变
String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。
private final char value[];
String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
char[] value;
StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如:
StringBuffer sb = new StringBuffer();
不能通过赋值符号对他进行赋值. , 如 sb = “welcome to here!”; ×
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法.
sb.append("hello");
②. 是否多线程安全
String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的 。看如下源码:
public synchronized StringBuffer reverse(){super.reverse();return this;
}public int indexOf(String str){return indexOf(str,0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法
}
StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的 。
③ StringBuilder与StringBuffer共同点
StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。
抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。
2. 包装类
包装类: 将基本数据类型做了封装,每一种基本数据类型都对应一种包装类型一切皆对象 - 引用, 基本数据类型不属于对象装箱:从基本类型转换为对应的包装类对象。拆箱:从包装类对象转换为对应的基本类型。
byte -> Byteshort -> Shortint -> Integerlong -> Longdouble -> Doublefloat -> Floatchar -> Characterboolean -> Boolean
Integer.parseInt("12a"); ->> NumberFormatExceptionInteger.toBinaryString() -> 将整数转换成二进制的字符串形式Integer.parseInt("12a", 16) -> 将字符串以16进制方式转换成数字// 1.1 int -> Integer 隐藏了自动装箱的操作i1 = i; // 等同于: i1 = Integer.valueOf(i);// 1.2 Integer -> int 隐藏了自动拆箱的操作i = i1; // 等同于: i = i1.intValue();所有的数值的包装类都拥有统一的父类: Number所有的包装类, 都是 final 类Integer常量池范围:-128~127
测试代码:
public class Demo01 {public static void main(String[] args) {//基本数据类型和包装类型之间可以直接转换int i = 1;Integer i1 = 2;System.out.println(i);System.out.println(i1);// i = i1.intValue();i = i1; //隐藏了自动装箱的操作System.out.println(i);//i1 = Integer.valueOf(i);i1 = i; //隐藏了自动拆箱的操作System.out.println(i1);//将字符串以16进制进行转换i1 = Integer.parseInt("ff", 16);System.out.println(i1);i1 = Integer.parseInt("1110", 2);System.out.println(i1);System.out.println();System.out.println("Byte.MAX_VALUE:\t"+Byte.MAX_VALUE);System.out.println("Byte.MIN_VALUE:\t"+Byte.MIN_VALUE);System.out.println("Short.MAX_VALUE:\t"+Short.MAX_VALUE);System.out.println("Short.MIN_VALUE:\t"+Short.MIN_VALUE);System.out.println("Integer.MAX_VALUE:\t"+Integer.MAX_VALUE);System.out.println("Integer.MIN_VALUE:\t"+Integer.MIN_VALUE);System.out.println("Long.MAX_VALUE:\t"+Long.MAX_VALUE);System.out.println("Long.MIN_VALUE:\t"+Long.MIN_VALUE);}
}