1.String类
String类在所有的项目开发中都会用到。
1.1实例化方式
直接赋值
String str = "hello world";
直接赋值方式最为常用。但是String本身毕竟是一个类,既然是类,那么类中一定存在构造方法。String类也不例外,String类的其中一种构造方法如下:
通过构造方法产生对象(构造方法赋值)
String str1 = new String ("hello world");
system.out.println(str1);
使用关键字new来进行实例化。
1.2.字符串的相等比较
"=="操作符用于比较两个变量的值是否相等。
对于基本类型而言,比较的就是数值大小;
对于引用类型而言,比较的实际上是保存的地址是否相等而不会比较内容。
所以在字符串内容比较时,需要使用String类提供的equals()方法,区分大小写
str1.equals(str2);
不区分大小写比较
equalsIgnoreCase() ;
例:比较两个字符串内容
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1.equals(str)); //结果为true
1.3 String的匿名对象
所有字符串常量 " " 都是String类的匿名对象。
在比较字符串是否等于特定字符串时,将字符串常量写在equals前。
String str = null ; // 假设由用户输入
System.out.println(str.equals("Hello")); //运行时出错
在进行接收用户输入数据的时候一定要考虑到用户没有输入的问题,以上面代码为例,用户没有输入的时候,一定会出现 NullPointerException 问题。
任何的字符串常量都是String的匿名对象,所以该对象永远不会为null。
所以我们在以后进行比较的时候,强烈建议把字符串写在前面。
String str = null ;
System.out.println("Hello".equals(str)); //结果为 false
1.4两种实例化方式的区别
直接赋值与构造赋值
直接赋值:
在JVM内部会维护一个字符串常量池(对象数组)。若采用直接赋值的方式进行string类的实例化操作,那么该对象会自动保存到对象池之中。若下一次继续使用直接赋值的方式实例化string对象,先在对象池中寻找是否有指定内容对象,若有,直接引用,否则创建新空间,将新对象入池以供下次使用。
构造赋值:
当使用构造方法实例化字符串时,实际上会开辟两次空间。
// 该字符串常量并没有保存在对象池之中
String str1 = new String("hello") ;
String str2 = "hello" ;
System.out.println(str1 == str2); //结果 false
实例化后的对象并不会保存到对象池中。可以使用intern()方法来手工入池
String str = "hello world";
String str1 = new String ("hello world").intern();
system.out.println(str == str1); //结果:true
1.5字符串常量不可变更
字符串一旦定义不可更改。堆中常量的值无法修改,但是栈中的指向可以更改。
String str = "hello" ;
str = str + " world" ;
str += "!!!" ;
System.out.println(str); // hello world!!!
以上字符串的变更是字符串对象的变更而非字符串常量。
我们进行内存分析可知:字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。
所以字符串不要改变太多次,慎用"+",避免形成大量垃圾空间。
1.6字符与字符串
范例:
String str = "helloworld" ;
// 将字符串变为字符数组
char[] data = str.toCharArray() ;
for (int i = 0; i < data.length; i++) {
data[i] -= 32 ;
System.out.print(data[i]+"、");
}
// 字符数组转为字符串
System.out.println(new String(data)); // 全部转换
System.out.println(new String(data,5,5)); // 部分转换
char[ ]–>String
public String (char [ ] value) :将字符数组全部转为字符串
public String (char [ ] value ,int offset ,int len);
将字符数组的部分内容转为字符串
string->char
public char charAt(int index):取得字符串指定索引的字符,从0开始
string->char [ ]
public char [ ] toCharArray():将字符串转为字符数组。
1.7字节与字符串
byte[ ]–>String
public String (byte [ ] value) :将字节数组全部转为字符串
public String (byte [] value ,int offset ,int len);
将字节数组的部分内容转为字符串
string->byte [ ]
public byte [ ] getbytes ( ):将字符串转为字节数组。
public byte [ ] getbytes (String charSet ):将字符串按照指定编码格式转为字节数组。
1.8字符串比较方法
比较相等
equals方法
equalsIgnoreCase 方法
范例:
String str1 = "hello" ;
String str2 = "Hello" ;
System.out.println(str1.equals(str2)); // false
System.out.println(str1.equalsIgnoreCase(str2)); // true
比较大小
public int compareTo(String anotherString):比较两个字符串的大小关系
在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内容:
—负数:小于
—0:相等
—正数:大于
范例:
System.out.println("A".compareTo("a")); // -32
System.out.println("a".compareTo("A")); // 32
System.out.println("A".compareTo("A")); // 0
System.out.println("AB".compareTo("AC")); // -1
System.out.println("刘".compareTo("杨"));
按照ASCII码比较,只要发现不相等的内容算出差值直接返回,不会继续向下查找。
1.9.字符串查找
主要有contain() indexOf() startWith() endsWith()等方法。
1.使用contains()方法进行查找
String str = "helloworld" ;
System.out.println(str.contains("world")); // true
2.使用indexOf()方法进行位置查找
String str = "helloworld" ;
System.out.println(str.indexOf("world")); // 5,w开始的索引
System.out.println(str.indexOf("bit")); // -1,没有查到
if (str.indexOf("hello") != -1) {
System.out.println("可以查到指定字符串!");
}
3.判断开头或结尾
String str = "**@@helloworld!!" ;
System.out.println(str.startsWith("**")); // true
System.out.println(str.startsWith("@@",2)); // ture
System.out.println(str.endsWith("!!")); // true
1.10字符串替换
public String replaceAll ( String regex ,String replacement):将字符串中所有指定内容替换为新内容。
public String replaceFirst ( String regex ,String replacement):替换首个内容。
范例:
String str = "helloworld" ;
System.out.println(str.replaceAll("l", "_")); //he__owor_d
System.out.println(str.replaceFirst("l", "_")); //he_loworld
1.11字符串拆分
public String [ ] split ( String regex):按照指定格式将字符串全部拆分。
public String [ ] split ( String regex ,int limit ):将字符串部分拆分,数组长度为限定limit长度。
范例:实现字符串的拆分处理
String str = "hello world hello sunshine" ;
String[] result = str.split(" ") ; // 按照空格拆分
for(String s: result) {
System.out.println(s);
}
范例:字符串的部分拆分
String str = "hello world hello sunshine" ;
String[] result = str.split(" ",2) ;
for(String s: result) {
System.out.println(s);
}
以上的拆分形式都很容易。如果发现有些内容无法拆分开就需要使用" \ "进行转义。
范例:拆分IP地址
String str = "192.168.1.1" ;
String[] result = str.split("\\.") ;
for(String s: result) {
System.out.println(s);
}
1.12字符串截取
public Striing substring( int beginIndex):从指定索引开始截取到字符串结尾。
public Striing substring( int beginIndex,int endIndex):从指定索引开始到指定位置结束。
范例:由以下代码可知,字符串的截取遵循左闭右开原则 [ )
String str = "helloworld" ;
System.out.println(str.substring(5)); //world
System.out.println(str.substring(0, 5)); //hello
1.13其他操作方法
trim ( ):去掉字符串左右两边空格,中间保留
String str = " hello world " ;
System.out.println("["+str+"]"); //[ hello world ]
System.out.println("["+str.trim()+"]"); //[ hello world ]
toUpperCase ( ):将字符串转大写处理
toLowerCase ( ):将字符串转小写处理
这两个函数只转换字母
String str = " hello%$$%@#$%world 哇哦 " ;
System.out.println(str.toUpperCase());
System.out.println(str.toLowerCase());
length ( ):返回字符串长度
String str = " hello%$$%@#$%world 哇哦 " ;
System.out.println(str.length());
注意:数组长度使用数组名称.length属性,而String中使用的是length()方法
isEmpty ( ):判断是否为空字符串,但不是null,而是长度为0。
System.out.println("hello".isEmpty());
System.out.println("".isEmpty());
System.out.println(new String().isEmpty());
1.14 StringBuffer、StringBuilder
—StringBuffer—
由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer类。
在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:
public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("Hello").append("World");
fun(sb);
System.out.println(sb);
}
public static void fun(StringBuffer temp) {
temp.append("\n").append("hello,world");
}
}
String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串的情况考虑使用StingBuffer。
注意:String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:
—String变为StringBuffer:利用StringBuffer的构造方法或append()方法。
—StringBuffer变为String:调用toString()方法。
除了append()方法外,StringBuffer也有一些String类没有的方法:
1.字符串反转reverse()
范例:
StringBuffer sb = new StringBuffer("helloworld");
System.out.println(sb.reverse()); //结果:dlrowolleh
2.删除指定范围的数据delete(int start , int end)
范例:
StringBuffer sb = new StringBuffer("helloworld");
System.out.println(sb.delete(5, 10)); //结果:hello
3.插入数据insert(int offset, 各种数据类型 b )
范例:
StringBuffer sb = new StringBuffer("helloworld");
System.out.println(sb.delete(5, 10).insert(0, "123")); //123hello
—StringBuilder—
和StringBuffer一样,而StringBuffer多了同步处理关键字。
面试题:请解释String与StringBuffer、StringBuilder的区别。
1.String常量内容不可修改,而StringBuffer与StringBuilder的内容可以修改。
2.StringBuffer使用同步处理,线程安全,性能较低。
StringBuilder使用异步处理,线程不安全,性能较高。
在普遍场景下,推荐使用StringBuffer。当String对象使用“+”进行字符串拼接时,javac编译器会将String对象变为StringBuilder而后调用append()来修改字符串内容,减少无用空间的开辟。