String类 PartII
- 三、StringBuilder和StringBuffer
- 四、相关OJ练习
- 4.1 [字符串中的第一个唯一字符](https://leetcode.cn/problems/first-unique-character-in-a-string/)
- 4.2 [字符串最后一个单词的长度](https://www.nowcoder.com/practice/8c949ea5f36f422594b306a2300315da?tpId=37&&tqId=21224&rp=5&ru=/activity/oj&qru=/ta/huawei/question-ranking)
- 描述
- 示例1
- 4.3 [验证回文串](https://leetcode.cn/problems/valid-palindrome/)
三、StringBuilder和StringBuffer
我们先来看一段代码:
public class TestDemo1 {
public static void main(String[] args) {
StringBuffer str = new StringBuffer("hello");
str.reverse();
System.out.println(str);
}
}
这就是字符串的逆置,很简单吧!
但是我们来看,这个位置为什么不接收返回值呢?对于字符串的操作不都是返回一个新数组的吗?
这就是我们要讨论的.
3.1 介绍
当对字符串进行修改的时候,需要使用 StringBuffer
和 StringBuilder
类。
和 String
类不同的是,StringBuffer
和 StringBuilder
类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder
类它和 StringBuffer
之间的最大不同在于 StringBuilder
的方法不是线程安全的(不能同步访问)。
由于 StringBuilder
相较于 StringBuffer
有速度优势,所以多数情况下建议使用 StringBuilder
类。
那么我们之前写的代码
public static void main(String[] args) {
String str = "hello";
for (int i = 0; i < 10; i++) {
str += i;
}
System.out.println(str);
}
如果要使用StringBuilder
就会解决之前我们说过的产生许多临时对象的问题
public static void main(String[] args) {
StringBuilder str = new StringBuilder("abc");
for (int i = 0; i < 10; i++) {
str.append(i);
}
System.out.println(str.toString());//abc0123456789
}
//注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
//String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
//StringBuilder变为String: 调用toString()方法
3.2 相关方法
-
append
:拼接字符串public class TestDemo1 { public static void main(String[] args) { StringBuffer str = new StringBuffer("hello"); str.append("!!!!"); str.append("ababa").append("haha");//可以连续拼接 System.out.println(str);//hello!!!!ababahaha System.out.println("------------------"); StringBuilder str2 = new StringBuilder("hey"); str2.append("boy").append("so cool"); System.out.println(str2);//heyboyso cool } }
-
reverse
:字符串逆置public class TestDemo1 { public static void main(String[] args) { StringBuffer str = new StringBuffer("hello"); str.reverse(); System.out.println(str); } }
-
insert
:在指定位置插入字符串public class TestDemo1 { public static void main(String[] args) { StringBuffer str = new StringBuffer("hello"); str.insert(0,"ab");//在偏移量为0(开头)的位置插入ab System.out.println(str);//abhello } }
-
之前的
String
的方法都可以使用
3.3 面试题
String
、StringBuffer
、StringBuilder
的区别
String
的内容不可修改,StringBuffer
与StringBuilder
的内容可以修改.StringBuffer
与StringBuilder
大部分功能是相似的StringBuffer
采用同步处理,属于线程安全操作;而StringBuilder
未采用同步处理,属于线程不安全操
作
- 以下总共创建了多少个
String
对象 [前提不考虑常量池之前是否存在]
String str = new String("ab"); // 会创建多少个对象
String str = new String("a") + new String("b"); // 会创建多少个对象
四、相关OJ练习
4.1 字符串中的第一个唯一字符
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。
示例 1:
输入: s = “leetcode”
输出: 0
示例 2:输入: s = “loveleetcode”
输出: 2
示例 3:输入: s = “aabb”
输出: -1提示:
1 <= s.length <= 105
s 只包含小写字母
public int firstUniqChar(String s) {
//好习惯->参数进行判断
if(s == null || s.length() == 0) {
return -1;
}
int[] array = new int[26];
for(int i = 0;i < s.length();i++) {
char ch = s.charAt(i);
array[ch - 'a']++;
}
for(int i = 0;i < s.length();i++) {
char ch = s.charAt(i);
if(array[ch - 'a'] == 1) {
return i;
}
}
return -1;
}
4.2 字符串最后一个单词的长度
描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
示例1
输入:
hello nowcoder
输出:
8
复制
说明:
最后一个单词为nowcoder,长度为8
//方法一
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine()) {
String str = scan.nextLine();
String[] strings = str.split(" ");
int count = strings.length - 1;
System.out.println(strings[count].length());
}
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine()) {
String str = scan.nextLine();
int index = str.lastIndexOf(" ");
String ret = str.substring(index+1);
System.out.println(ret.length());
}
}
4.3 验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
解释:“amanaplanacanalpanama” 是回文串
示例 2:输入: “race a car”
输出: false
解释:“raceacar” 不是回文串提示:
1 <= s.length <= 2 * 105
字符串 s 由 ASCII 字符组成
思路:
- 判断数字和字母
- 把整个字符串都转换成小写
- 不是数字和字母的跳过这个元素
- 是数字和字母的判断是否相等,相等的话继续接着比较,不相等的话返回
false
.直到所有字符比较完成,返回true
class Solution {
private boolean isCharacter(char ch) {
if(ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
return true;
}
return false;
}
public boolean isPalindrome(String s) {
s = s.toLowerCase();
int i = 0;
int j = s.length() - 1;
while(i < j) {
while(i < j && !isCharacter(s.charAt(i))) {
i++;
}
while(i < j && !isCharacter(s.charAt(j))) {
j--;
}
if(s.charAt(i) != s.charAt(j)) {
return false;
} else {
i++;
j--;
}
}
return true;
}
}