總結一些個人字符串的心得,也方便做string類的面試題能靈活運用
關於字符串對象的一些常用套路(方法)
將數字轉換成字符串:任何基本類型包裝類都有toString() ,將數字轉換成字符串
將字符串轉成數字: 每個基本類型包裝類 都有:
(注意:如果字符串格式不正確,則轉換為數字不會成功,報異常)
Integer.parseInt(s)
Long.parseLong(s);
Byte.parseByte(s)
Float.parseFloat(s);
字符數組-->字符串 :String a = new String(字符數組);
字符串--> 字符數組 : str.toCharArray();
錯誤用法:String b = 'A'+'B' ; (編譯報錯)
錯誤用法:String c = 'a'; //不能夠直接把一個字符轉換成字符串
正確:String d = Character.toString('a'); //一個字符轉換為字符串
拿出字符串中的某個字符 : char c = str.charAt(index); 字符串取出一個字符
字符串對象的方法:
charAt() --獲取字符
toCharArray(字符串) --獲取對應的字符數組
subString() --截取子字符串
split() --分隔
trim() --去掉首尾空格
toLowerCase(字符串) --大小寫
toUpperCase(字符串) --大小寫
(筆記:字符串對象的方法,只能整體轉換大小寫,很不靈活,還是得用到Character的轉換大小寫)
indexOf(字符串) --定位
lastIndexOf(字符串) --定位
contains(字符串) --定位
replaceAll () --替換
replaceFirst --替換
=============================
字符靜態方法:
Character.isLetter('a'));//判斷是否為字母
Character.isDigit('a')); //判斷是否為數字
Character.isWhitespace(' ')); //是否是空白
Character.isUpperCase('a')); //是否是大寫
Character.isLowerCase('a')); //是否是小寫
Character.toUpperCase('a')); //轉換為大寫
Character.toLowerCase('A')); //轉換為小寫
========================================
StringBuffer的好用方法
append 追加
delete 刪除
nsert 插入
reverse 反轉
length 長度
capacity 容量(默認一開始就占19)
為什么StringBuffer可以變長?
答:StringBuffer和String內部是一個字符數組一樣,StringBuffer也維護了一個字符數組。 但是,這個字符數組,留有冗余長度
本文最底部,有一個模擬StringBuffer是如何實現的過程
分割線=========
自動裝箱
不需要調用構造方法,通過=符號自動把 基本類型 轉換為 類類型 就叫裝箱
int i = 5;
//基本類型轉換成封裝類型
Integer it = new Integer(i); //裝箱-》實質它做了這個操作
//自動轉換就叫裝箱
Integer it2 = i;
自動拆箱
int i = 5;
Integer it = new Integer(i);
//封裝類型轉換成基本類型
int i2 = it.intValue(); // 拆箱-》實質它做了這個操作
//自動轉換就叫拆箱
int i3 = it;
}
題目1
- 對byte,short,float,double進行自動拆箱和自動裝箱
- byte和Integer之間能否進行自動拆箱和自動裝箱
- 通過Byte獲取byte的最大值
總結;
數字轉字符串 : String.valueof(int)
字符串轉數字:Integer.parseInt(str);
題目2
把浮點數 3.14 轉換為 字符串 "3.14"
再把字符串 “3.14” 轉換為 浮點數 3.14
如果字符串是 3.1a4,轉換為浮點數會得到什么?
題目3
這個圖是自然對數的計算方式。
借助Math的方法,把自然對數計算出來,看看經過自己計算的自然對數和Math.E的區別有多大
答案
題目4 --質數
統計找出一千萬以內,一共有多少質數
質數概念: 只能被1和自己整除的數
舉例:
5只能被 1和5整除,所以是質數
8可以被2整除,所以不是質數
答案
格式化輸出筆記
如果不使用格式化輸出,就需要進行字符串連接,如果變量比較多,拼接就會顯得繁瑣
使用格式化輸出,就可以簡潔明了
%s 表示字符串
%d 表示數字
%n 表示換行
printf和format能夠達到一模一樣的效果,如何通過eclipse查看java源代碼 可以看到,在printf中直接調用了format
題目5
借助Scanner 讀取字符串數據,然后用格式化輸出下面
浙江溫州最大皮革廠江南皮革廠倒閉了,王八蛋老板黃鶴吃喝嫖賭,欠下了3.5個億,帶着他的小姨子跑了!我們沒有辦法,拿着錢包抵工資!原價都是一百多、兩百多、三百多的錢包,現在全部只賣二十塊,統統只要二十塊!黃鶴王八蛋,你不是人!我們辛辛苦苦給你干了大半年,你不發工資,你還我血汗錢,還我血汗錢!
筆記
java的換號符號是 \r\n
假如想用printf 那么就是直接%n
補充其他常用的格式化
題目6 --Character
通過Scanner從控制台讀取字符串,然后把字符串轉換為字符數組
轉換為字符數組后,篩選出控制台讀取到的字符串中的大寫字母和數字,並打印出來
package zsc.czy.number;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str = s.nextLine();
char[] c = str.toCharArray();
for(char one :c){
if(Character.isUpperCase(one)){
System.out.println(one);
}
if(Character.isDigit(one)){
System.err.println(one);
}
}
}
}
筆記: 一般一個A類. XX() 都是意味着將本A類型轉換成括號里的類型。
字符串對象有一個toCharArray(),可以直接將字符串轉換為字符數組,一開始我還以為有String靜態方法會提供此功能
字符數組 轉成String 的方法是: String result2 = new String(字符數組);
筆記:
String.format(sentenceFormat, name,kill,title); 的好處是 它是返回一個字符串,方便控制,而用printf(sentenceFormat, name,kill,title)) 或System.out.format(sentenceFormat, name,kill,title);則是直接就打印出來的
題目7 --隨機字符串
創建一個長度是5的隨機字符串,隨機字符有可能是數字,大寫字母或者小寫字母
給點提示: 數字和字符之間可以通過互相轉換
方法1:
package zsc.czy.number;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
char cs[] =new char[5];
char startC = '0';
char endC ='z'; //小轉大,會自動強轉
int start =startC;
int end = endC;
System.out.println(start); //48
System.out.println(end); //122
for(int i =0;i<cs.length;i++){
while(true){
char c= (char)((Math.random()*(end-start)+start));
//122-48=74 [0.0,1.0) 最小0*74+48 ,最大1.0*74+48=122
if (Character.isLetter(c) || Character.isDigit(c)) {
cs[i] = c;
break;
}
}
}
}
}
方法2
package zsc.czy.number;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool += (char) i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool += (char) i;
}
char cs2[] = new char[5];
for (int i = 0; i < cs2.length; i++) {
int index = (int) (Math.random() * pool.length());
cs2[i] = pool.charAt(index);
}
String result2 = new String(cs2);
System.out.println(result2);
}
}
題目8-字符串數組排序
創建一個長度是8的字符串數組
使用8個長度是5的隨機字符串初始化這個數組
對這個數組進行排序,按照每個字符串的首字母排序(無視大小寫)
注1: 不能使用Arrays.sort() 要自己寫
注2: 無視大小寫,即 Axxxx 和 axxxxx 沒有先后順序
提示:排序的時候,借助冒泡法的思路比較邏輯是每個字符串的第一個字符,並且都轉換為小寫,從而達到無視大小寫的效果
package zsc.czy.number;
import java.util.Arrays;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
String []str = new String[8];
for(int i =0;i<str.length;i++){
str[i]= makeStr();
}
System.out.println("排序前"+Arrays.toString(str));
for (int j = 0; j < str.length; j++) {
for (int i = 0; i < str.length - j - 1; i++) {
char firstChar1 = str[i].charAt(0);
char firstChar2 = str[i + 1].charAt(0);
firstChar1 = Character.toLowerCase(firstChar1);
firstChar2 = Character.toLowerCase(firstChar2);
if (firstChar1 > firstChar2) {
String temp = str[i];
str[i] = str[i + 1];
str[i + 1] = temp;
}
}
}
System.out.println("排序后"+Arrays.toString(str));
}
public static String makeStr(){
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool+=(char)i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool+=(char)i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool+=(char)i;
}
char cs2[] = new char[5];
for (int i = 0; i < cs2.length; i++) {
int index = (int) (Math.random()*pool.length());
cs2[i] = pool.charAt( index );
}
String result2 = new String(cs2);
return result2;
}
}
筆記:只有Character類才有判斷是不是數字 是不是英文,是不是空行 是不是大小寫 這些功能
Character.toLowerCase(X) 轉變成小寫
Character.isLowerCase(X) 判斷小寫
Character.isDigit(X) 數字
Character.isLetter(ch) 判斷
Character.isLetterOrDigit(X) 可以判斷是字母還是數字
另外,charAt 是 字符串對象里的方法 ,可以獲得單個字符
題目9-窮舉法破解密碼
-
生成一個長度是3的隨機字符串,把這個字符串作為當做密碼
-
使用窮舉法生成長度是3個字符串,匹配上述生成的密碼
要求: 分別使用多層for循環 和 遞歸解決上述問題
普通方法1
package zsc.czy.number;
import java.util.Arrays;
import java.util.Scanner;
public class TestNumber {
public static void main(String[] args) {
String password = randomString(3);
System.out.println("密碼是:" + password);
char[] guessPassword = new char[3];
outloop: for (short i = '0'; i <= 'z'; i++) {
for (short j = '0'; j <= 'z'; j++) {
for (short k = '0'; k <= 'z'; k++) {
if (!isLetterOrDigit(i, j, k))
continue;
guessPassword[0] = (char) i;
guessPassword[1] = (char) j;
guessPassword[2] = (char) k;
String guess = new String(guessPassword);
System.out.println("窮舉出來的秘密是:" + guess);
if (guess.equals(password)) {
System.out.println("找到了,密碼是" + guess);
break outloop;
}
}
}
}
}
private static boolean isLetterOrDigit(short i, short j, short k) {
return Character.isLetterOrDigit(i) && Character.isLetterOrDigit(j)
&& Character.isLetterOrDigit(k);
}
private static String randomString(int length) {
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool += (char) i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool += (char) i;
}
char cs[] = new char[length];
for (int i = 0; i < cs.length; i++) {
int index = (int) (Math.random() * pool.length());
cs[i] = pool.charAt(index);
}
String result = new String(cs);
return result;
}
}
方法2-遞歸
package zsc.czy.number;
public class Digui {
public static boolean found = false;
public static void main(String[] args) {
String password = randomString(3);
System.out.println("密碼是:" + password);
char[] guessPassword = new char[password.length()];
generatePassword(guessPassword, password);
}
public static void generatePassword(char[] guessPassword, String password) {
generatePassword(guessPassword, 0, password);
}
public static void generatePassword(char[] guessPassword, int index,
String password) {
if (found)
return;
for (short i = '0'; i <= 'z'; i++) {
char c = (char) i;
if (!Character.isLetterOrDigit(c))
continue;
guessPassword[index] = c;
if (index != guessPassword.length - 1) {
generatePassword(guessPassword, index + 1, password);
} else {
String guess = new String(guessPassword);
// System.out.println("窮舉出來的秘密是:" + guess);
if (guess.equals(password)) {
System.out.println("找到了,密碼是" + guess);
found = true;
return;
}
}
}
}
private static String randomString(int length) {
String pool = "";
for (short i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (short i = 'a'; i <= 'z'; i++) {
pool += (char) i;
}
for (short i = 'A'; i <= 'Z'; i++) {
pool += (char) i;
}
char cs[] = new char[length];
for (int i = 0; i < cs.length; i++) {
int index = (int) (Math.random() * pool.length());
cs[i] = pool.charAt(index);
}
String result = new String(cs);
return result;
}
}
字符串對象的方法
上面這些都是字符串對象的方法
題目10--每個單詞的首字母都轉換為大寫
給出一句英文句子: "let there be light"
得到一個新的字符串,每個單詞的首字母都轉換為大寫
提示:這里題目說是首字母,所以還是得用到Character 來單個轉換大小寫,因為字符串對象只提供全部轉大小寫的功能
package zsc.czy.number;
import java.util.Arrays;
public class A {
public static void main(String[] args) {
String s = "let there be light";
String Words[]=s.split(" ");
System.out.println(Arrays.toString(Words));//[let, there, be, light]
for(int i =0;i<Words.length;i++){
char upperFirstWord =Character.toUpperCase(Words[i].charAt(0));
String rest = Words[0].substring(1); //拿到一組單詞的除首位后的字符串
String newWord= upperFirstWord+rest ; //首位大字母和 余字符串拼接
Words[i] = newWord;
}
System.out.println(Arrays.toString(Words));//[Let, Tet, Bet, Let]
//開始將數組轉回字符串
StringBuffer sb = new StringBuffer();
for(String word :Words){
sb.append(word+" ");
}
System.out.println(sb.toString());
}
}
題目11--英文繞口令
英文繞口令
peter piper picked a peck of pickled peppers
統計這段繞口令有多少個以p開頭的單詞
package zsc.czy.number;
public class B {
public static void main(String[] args) {
String s = "peter piper picked a peck of pickled peppers";
String words[] = s.split(" ");
int count=0;
for(int i=0;i<words.length;i++){
if(words[i].charAt(0)=='p'){
count++;
}
}
System.out.println(count);
}
}
題目11--練習-間隔大寫小寫模式
把 lengendary 改成間隔大寫小寫模式,即 LeNgEnDaRy
package zsc.czy.number;
public class E {
public static void main(String[] args) {
String s = "lengendary";
//字符串轉數組
char []c = s.toCharArray();
StringBuffer sb = new StringBuffer();
for(int i = 0;i<s.length();i++){
if(i%2==0){
char UpperWord=Character.toUpperCase(c[i]);
sb.append(UpperWord);
}
if(i%2 ==1){
char lowWord = Character.toLowerCase(c[i]);
sb.append(lowWord);
}
}
System.out.println( sb.toString());
}
}
另一做法:
public class TestString {
public static void main(String[] args) {
// 把 lengendary 改成間隔大寫小寫模式,即 LeNgEnDaRy
String s = "lengendary";
char[] cs =s.toCharArray();
int count= 0;
for (int i = 0; i < cs.length; i++) {
if(0==i%2)
cs[i] = Character.toUpperCase(cs[i]);
}
String result = new String(cs);
System.out.printf(result);
}
}
題目12--練習-最后一個字母變大寫
把 lengendary 最后一個字母變大寫
package zsc.czy.number;
public class F {
public static void main(String[] args) {
String s = " lengendary";
char c[] = s.toCharArray();
c[c.length-1]= Character.toUpperCase(c[c.length-1]);
String str = new String(c);
System.out.println(str);
}
}
題目13-- -把最后一個two單詞首字母大寫
Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak
把最后一個two單詞首字母大寫
package zsc.czy.number;
public class G {
public static void main(String[] args) {
String s = "Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak";
int i =s.lastIndexOf("two");
System.out.println(i); //35
char c[] = s.toCharArray();
c[i] = Character.toUpperCase(c[i]);
System.out.println(c[i]); //T
String str = new String(c);
System.out.println(str);
}
}
筆記:字符串對象
startsWith //以...開始
endsWith //以...結束
題目13--比較字符串
創建一個長度是100的字符串數組
使用長度是2的隨機字符填充該字符串數組
統計這個字符串數組里重復的字符串有多少種
package zsc.czy.number;
import java.util.Arrays;
public class H {
static String[] foundDuplicated = new String[100];
static int pos;
public static void main(String[] args) {
String s[] = new String[100];
for (int i = 0; i < s.length; i++) {
s[i] = radomString(2);
}
int count=0 ;
System.out.println(Arrays.toString(s));
for (String s1 : s) {
int repeat = 0;
for (String s2 : s) {
if (s1.equalsIgnoreCase(s2)) {
repeat++;
if (2 == repeat) {
// 當repeat==2的時候,就找打了一個非己的重復字符串
putIntoDuplicatedArray(s1);
break;
}
}
}
}
System.out.printf("總共有 %d種重復的字符串%n", pos);
if (pos != 0) {
System.out.println("分別是:");
for (int i = 0; i < pos; i++) {
System.out.print(foundDuplicated[i] + " ");
}
}
}
private static void putIntoDuplicatedArray(String s1) {
for (int i = 0; i < pos; i++){
if (foundDuplicated[i].equalsIgnoreCase(s1))
return;
}
foundDuplicated[pos++] = s1;
}
public static String radomString(int length) {
String pool = "";
for (int i = '0'; i <= '9'; i++) {
pool += (char) i;
}
for (int j = 'A'; j <= 'Z'; j++) {
pool += (char) j;
}
for (int k = 'a'; k <= 'z'; k++) {
pool += (char) k;
}
// int i = (int) (Math.random() * pool.length());
// int j = (int) (Math.random() * pool.length());
// char c[] = pool.toCharArray();
// String first = new String(Character.toString(c[i]));
// String second = new String(Character.toString(c[j]));
// String newStr = first + second;
char cs[] = new char[length];
for (int i = 0; i < cs.length; i++) {
int index = (int)(Math.random()*pool.length());
cs[i]=pool.charAt(index);
}
String result = new String(cs);
return result;
}
}
題目14--StringBuffer性能
String與StringBuffer的性能區別?
生成10位長度的隨機字符串
然后,先使用String的+,連接10000個隨機字符串,計算消耗的時間
然后,再使用StringBuffer連接1000000個隨機字符串,計算消耗的時間
package zsc.czy.number;
public class J {
public static void main(String[] args) {
int total = 10000;
String s = randomString(10);
StringBuffer sb = new StringBuffer();
String str1 = "";
long start = System.currentTimeMillis();
for (int i = 0; i < total; i++) {
str1 += s;
}
long end = System.currentTimeMillis();
System.out.printf("使用字符串連接+的方式,連接%d次,耗時%d毫秒%n", total, end - start);
total *= 100;
start = System.currentTimeMillis();
for (int i = 0; i < total; i++) {
sb.append(s);
}
end = System.currentTimeMillis();
System.out.printf("使用StringBuffer的方式,連接%d次,耗時%d毫秒%n", total, end
- start);
//
// String ss[] = new String[10];
// String connectStr = null;
// long start = System.currentTimeMillis();
// for(int i =0;i<ss.length;i++){
// ss[i]=randomString(10);
// connectStr += ss[i];
// }
// long end = System.currentTimeMillis();
// System.out.println("用時:"+(end-start)); //打印用時:6
//奇怪,為何不用printf的話,打印的會是一個整數?
}
public static String randomString(int length) {
String pools = "";
for (int i = '0'; i < '9'; i++) {
pools += (char) i;
}
for (int j = 'a'; j < 'z'; j++) {
pools += (char) j;
}
for (int k = 'A'; k < 'Z'; k++) {
pools += (char) k;
}
char cs[] = new char[length];
for (int l = 0; l < cs.length; l++) {
int index = (int) (Math.random() * pools.length());
cs[l] = pools.charAt(index);
}
String newStr = new String(cs);
return newStr;
}
}
輸出結果
三百倍的效率
題目15---MyStringBuffer
根據接口IStringBuffer ,自己做一個MyStringBuffer
原理
為什么StringBuffer可以變長?
和String內部是一個字符數組一樣,StringBuffer也維護了一個字符數組。 但是,這個字符數組,留有冗余長度
比如說new StringBuffer("the"),其內部的字符數組的長度,是19,而不是3,這樣調用插入和追加,在現成的數組的基礎上就可以完成了。
如果追加的長度超過了19,就會分配一個新的數組,長度比原來多一些,把原來的數據復制到新的數組中,看上去 數組長度就變長了 參考MyStringBuffer
length: “the”的長度 3
capacity: 分配的總空間 19
注: 19這個數量,不同的JDK數量是不一樣的
======================================
自己模擬一StringBuffer
package zsc.czy.number;
public class MyStringBuffer implements IStringBuffer {
int capacity = 16;
int length = 0;
char[] value;
public MyStringBuffer() {
value = new char[capacity];
}
public MyStringBuffer(String str) {
this();
if (null == str) {
return;
}
// 如果容量比傳入的字符串長度小,那么就增大2倍容量
if (capacity < str.length()) {
capacity = value.length * 2;
value = new char[capacity];
}
if (capacity >= str.length()) {
System.arraycopy(str.toCharArray(), 0, value, 0, str.length());
}
length = str.length(); // 字符數組的長度
}
@Override
public void append(String str) {
insert(length, str);
}
@Override
public void append(char c) {
append(String.valueOf(c));
}
@Override
public void insert(int pos, char b) {
}
@Override
public void insert(int pos, String b) {
// 邊界條件判斷
if (pos < 0)
return;
if (pos > length)
return;
if (null == b)
return;
// 擴容
while (length + b.length() > capacity) {
capacity = (int) ((length + b.length()) * 1.5f);
// 發現插入的字符串比原有的字符數組大 就重新new一個更大的出來,並復制到新的數組,然后改變引用指向
char[] newValue = new char[capacity];
System.arraycopy(value, 0, newValue, 0, length);
value = newValue;
}
// 如果原來字符數組的空間還有足夠空間放得下新字符串里的字符的話
char[] cs = b.toCharArray();
// 先把已經存在的數據往后移
// 下面這句話需要理解
System.arraycopy(value, pos, value, pos + cs.length, length - pos);
// 把要插入的數據插入到指定位置
System.arraycopy(cs, 0, value, pos, cs.length);
length = length + cs.length;
}
@Override
public void delete(int start) {
}
@Override
public void delete(int start, int end) {
// 邊界條件判斷
if (start < 0)
return;
if (start > length)
return;
if (end < 0)
return;
if (end > length)
return;
if (start >= end)
return;
System.arraycopy(value, end, value, start, length - end);
length -= end - start;
}
@Override
public void reverse() {
// 1.
// 首尾 互換
for (int i = 0; i < length / 2; i++) {
char temp = value[i];
value[i] = value[length - i - 1];
value[i] = value[length - i - 1] = temp;
}
}
@Override
public String toString() {
char[] realValue = new char[length];
System.arraycopy(value, 0, realValue, 0, length);
return new String(realValue);
}
@Override
public int length() {
return 0;
}
public static void main(String[] args) {
MyStringBuffer sb = new MyStringBuffer("there light");
sb.reverse();
System.out.println(sb);
}
}