字符串知识点总结
在Java语言中,字符串起着非常重要的作用,字符串的声明与初始化主要有如下两种情况:
1)对于String s1=new String(“abc”)语句与String s2=new String(“abc”)语句,存在两个引用对象s1、s2,两个内容相同的字符串对象”abc”,它们在内存中的地址是不同的。只要用到new总会生成新的对象。
2)对于String s1=”abc”语句与String s2=”abc”语句,在JVM中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,s1、s2引用的是同一个常量池中的对象。由于String的实现采用了Flyweight的设计模式,当创建一个字符串常量时,例如String s = “abc”,会首先在字符串常量池中查找是否已经有相同的字符串被定义,其判断依据是String类equals(Object obj)方法的返回值。若已经定义,则直接获取对其的引用,此时不需要创建新的对象;若没有定义,则首先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。由于String类是不可变类,一旦创建好了就不能被修改,因此String对象可以被共享而且不会导致程序的混乱。
常见笔试题:
1、对于String类型的变量s,赋值语句s=null与s=””是否相同?
答:对于赋值语句s=null,其中s是一个字符串类型的引用,它不指向任何一个字符串。而赋值语句s=””中的s是一个字符串类型的引用,它指向另外 一个字符串(这个字符串的值为””,即空字符串),因此,这两者是不同的。
2. new String(“abc”)创建了几个对象?
答:一个或两个。如果常量池中原来有”abc”,那么只创建一个对象;如果常量池中原来没有字符串”abc”,那么就会创建两个对象。
“==”、equals和hashCode有什么区别?
答:1)”==”比较的是地址。
3)equals()是Object类提供的方法之一。在没有重写Object类中equals()方法的情况下,equals()与”==”运算符一样,比较的是地址。
4)hashCode()是Object类提供的方法之一。在没有重写Object类中hashCode()方法的情况下,hashCode()返回的是对象的内存地址,任何对象的hashCode()方法都是不相等的。
为什么重写了equals()方法,就一定要重写hashCode()方法?
答:equals()方法和hashCode()方法都是定义在Object类中的方法,在未被重写时,equals()方法利用”==”来比较两个对象的内存地址是否相同,调用hashCode()方法返回的是该对象的内存地址。
如果equals()方法返回true,那么两个对象的hashCode()方法返回值必须一样。
假设两个对象,重写了equals()方法,它们相等的条件是内容相等就返回true。如果不重写hashCode()方法,其返回的依然是两个对象的内存地址值,必然不相等。这就出现了equals()相等,hashCode()不相等的情况,违背了hashCode的规则。
常见笔试题:
1. 假设有以下代码String s=”hello”;String t=”hello”;char[] c={‘h’,’e’,’l’,’l’,’o’},下列选项中返回false语句的是(B)
A、s.equals(t) B、t.equals(c) C、s==t D、t.equals(new String(“hello”))
2. 下列程序的输出结果是什么?
String s=”abc”;
String s1=”ab”+”c”;
System.out.println(s==s1);
答案:true。”ab”+”c”在编译器就被转换为”abc”,存放在常量区,因此输出结果为true。
3. Set里的元素时不能重复的,那么用什么方法来区分是否重复呢?是用“==”还是equals()?它们有什么差别?
答案:用equals()方法来区分是否重复。equals()方法来区分是否重复。equals()方法与”==”运算符的区别见上面讲解。
4. String、StringBuffer、StringBuilder的区别?
答:String是不可变字符串,StringBuffer和StringBuilder都是可变字符串;StringBuffer是同步的,线程安全、效率高,StringBuilder是不同步的,线程不安全、效率低。
5. String类中compareTo()方法的源码解析:
答:1、首先获取到两个字符串中长度较小的那个,定义为minLength。
2、将两个字符串转成字符数组
3、根据minLength,遍历两个字符数组中的各个字符,一对一进行比较。如果相等,比较下一对字符;如果不相等,返回两个字符相减后的结果
4、如果在minLength范围内,字符均相等,那么返回两个字符串长度相减后的结果
正数:大
负数:小
0 :相等
6.String类常用方法有哪些?
答:charAt(int index) 获得指定位置字符
equals(Object s) 比较字符串内容
indexOf(String s) 寻找子串位置
lastIndexOf(String s) 从后向前寻找子串
length() 长度
substring(int start) 截取从指定位置到末尾的子串
substring(int start, int end) 截取 [start, end) 范围的子串
trim() 去除两端空白字符
compareTo(String s) 比较字符串大小,按字符编码比大小
contains(String s) 是否包含子串
equalsIgnoreCase(String s) 忽略大小写比较
replace(char c1, char c2) 替换字符,汇创建新对象
toCharArray() 转成 char[] 数组
toLowerCase() 转为小写,会创建新对象
toUpperCase() 转为大写,汇创建新对象
7.StringBuffer和数组的区别?
答:StringBuffer和数组都可以看作是一个容器,用来存放其它数据;
StringBuffer的数据最终是一个字符串数据,而数组可以存放多种数据,但必须是同一种数据类型。
8.看程序写结果
* 3:形式参数问题 * String作为参数传递 * StringBuffer作为参数传递 * * 形式参数: * 基本类型:形式参数的改变不影响实际参数 * 引用类型:形式参数的改变直接影响实际参数 * * 注意: * String作为参数传递,效果和基本类型作为参数传递是一样的。 */ public class Test{ public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; System.out.println(s1 + "---" + s2);// hello---world change(s1, s2); System.out.println(s1 + "---" + s2);// hello---world
StringBuffer sb1 = new StringBuffer("hello"); StringBuffer sb2 = new StringBuffer("world"); System.out.println(sb1 + "---" + sb2);// hello---world change(sb1, sb2); System.out.println(sb1 + "---" + sb2);// hello---worldworld
}
public static void change(StringBuffer sb1, StringBuffer sb2) { sb1 = sb2;//对地址进行操作 sb2.append(sb1);//对内容进行操作 }
public static void change(String s1, String s2) { s1 = s2; s2 = s1 + s2; } }
|
案例1:去除字符串中重复的字符
package 字符串去重复案例;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List;
/** * 去除字符串中重复的字符 * * @author Administrator * */ public class StringRemoveDuplicate {
public static void main(String[] args) { while(true){ //键盘录入一个字符串 System.out.println("请输入一个字符串:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = null; try { str = br.readLine(); //如果键盘录入“886”,结束循环 if(str.equals("886")){ return; } //调用方法去除字符串中重复的字符 String result = removeDuplicate(str); System.out.println("去重复后的字符串为:"); System.out.println(result); } catch (IOException e) { e.printStackTrace(); } } }
private static String removeDuplicate(String str) { char[] chars = str.toCharArray(); List list = new ArrayList(); StringBuffer sb = new StringBuffer(); for(int i=0;i<chars.length;i++){ if(!list.contains(chars[i])){ sb = sb.append(chars[i]); list.add(chars[i]); } }
return sb.toString(); } } |
案例2:反转字符串(方法1)
package 反转字符串;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /* * 字符串反转 * 举例:键盘录入”abc” * 输出结果:”cba” * * 分析: * A:键盘录入一个字符串 * B:定义一个新字符串 * C:倒着遍历字符串,得到每一个字符 * a:length()和charAt()结合 * b:把字符串转成字符数组 * D:用新字符串把每一个字符拼接起来 * E:输出新串 */ public class ReverseString{ public static void main(String[] args) { // 键盘录入一个字符串 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = null; try { br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 改进为功能实现 String s = myReverse(str); System.out.println("实现功能后的结果是:" + s); }
/* * 两个明确: 返回值类型:String 参数列表:String */ public static String myReverse(String s) { // 定义一个新字符串 String result = "";
// 把字符串转成字符数组 char[] chs = s.toCharArray();
// 倒着遍历字符串,得到每一个字符 for (int x = chs.length - 1; x >= 0; x--) { // 用新字符串把每一个字符拼接起来 result += chs[x]; } return result; } } |
反转字符串(方法2)
package 反转字符串;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
/* * 字符串反转 * */ public class ReverseString2{ public static void main(String[] args) { // 键盘录入一个字符串 System.out.println("请输入一个字符串:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = null; try { str = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 改进为功能实现 String s = myReverse(str); System.out.println("实现反转后的结果是:" + s); }
/* * 两个明确: 返回值类型:String 参数列表:String */ public static String myReverse(String s) { StringBuffer sb = new StringBuffer(s); String result = sb.reverse().toString(); return result; } } |
案例3:判断两个字符串是否由相同的字符组成(abcd和adcd一样)
package 判断两个字符串是否由相同的字符组成;
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Arrays;
/** * 判断两个字符串是否由相同的字符组成 * @author Administrator * */ public class IsEquals { public static void main(String[] args) throws Exception{ //键盘录入一个字符串 System.out.println("请输入一个字符串:"); BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in)); String str1 = br1.readLine(); //键盘再录入一个字符串 System.out.println("请再输入一个字符串:"); BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in)); String str2 = br2.readLine();
//调用方法,判断两个字符串是否由相同字符组成 boolean result = isEquals(str1,str2); System.out.println(result);
}
/** * 比较两个字符串是否由相同的字符组成 * * @param str1 * @param str2 * @return */ private static boolean isEquals(String str1, String str2) { //String类的toCharArray()方法,将字符串转换为字符数组 char[] chars1 = str1.toCharArray(); char[] chars2 = str2.toCharArray();
//对字符数组进行排序 Arrays.sort(chars1); Arrays.sort(chars2);
//String类的valueOf()方法,将字符数组转换为字符串 String charsToString1 = String.valueOf(chars1); String charsToString2 = String.valueOf(chars2);
//判断字符串是否相等 if(charsToString1.equals(charsToString2)){ return true; }else{ return false; } } } |
案例4.如何统计一行字符中有多少个单词
package 如何判断一行字符中有多少个单词;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
public class WordCount { public static void main(String[] args) throws IOException{ while(true){ //键盘录入一行字符 System.out.println("请输入一行字符:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); String[] strs = str.split(" "); int count = 0; for(int i=0;i<strs.length;i++){ if(strs[i].equals("")){ continue; } count++; } //打印一行字符中包含的单词个数 System.out.println(count); } } }
|
案例5.统计字符串中大写、小写、数字字符的个数
package 统计字符串中大小写数字字符的个数;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
/* * 需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数。(不考虑其他字符) * 举例: * "Hello123World" * 结果: * 大写字符:2个 * 小写字符:8个 * 数字字符:3个 * * 分析: * 前提:字符串要存在 * A:定义三个统计变量 * bigCount=0 * smallCount=0 * numberCount=0 * B:遍历字符串,得到每一个字符。 * length()和charAt()结合 * C:判断该字符到底是属于那种类型的 * 大:bigCount++ * 小:smallCount++ * 数字:numberCount++ * * 这道题目的难点就是如何判断某个字符是大的,还是小的,还是数字的。 * ASCII码表: * 048 * A65 * a97 * 虽然,我们按照数字的这种比较是可以的,但是想多了,有比这还简单的 * char ch = s.charAt(x); * * if(ch>='0' && ch<='9') numberCount++ * if(ch>='a' && ch<='z') smallCount++ * if(ch>='A' && ch<='Z') bigCount++ *D:输出结果。 * * 练习:把给定字符串的方式,改进为键盘录入字符串的方式。 */ public class StringTest2 { public static void main(String[] args) { //键盘录入一个字符串 System.out.println("请输入一个字符串:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; try { s = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
//定义三个统计变量 int bigCount = 0; int smallCount = 0; int numberCount = 0;
//遍历字符串,得到每一个字符。 for(int i=0; i<s.length(); i++){ char ch = s.charAt(i);
//判断该字符到底是属于那种类型的 if(ch>='a' && ch<='z'){ smallCount++; }else if(ch>='A' && ch<='Z'){ bigCount++; }else if(ch>='0' && ch<='9'){ numberCount++; } }
//输出结果。 System.out.println("大写字母"+bigCount+"个"); System.out.println("小写字母"+smallCount+"个"); System.out.println("数字"+numberCount+"个"); } } |
案例6.将字符串的首字母改成大写,其它改小写
package 将字符串的首字母改成大写其它改小写;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
/* * 需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符) * 举例: * helloWORLD * 结果: * Helloworld * * 分析: * A:先获取第一个字符 * B:获取除了第一个字符以外的字符 * C:把A转成大写 * D:把B转成小写 * E:C拼接D */ public class StringTest { public static void main(String[] args) { // 键盘录入一个字符串(只包含大、写字母) System.out.println("请输入一个字符串(只包含大、写字母):"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; try { s = br.readLine(); } catch (IOException e) { e.printStackTrace(); }
// 先获取第一个字符 String s1 = s.substring(0, 1); // 获取除了第一个字符以外的字符 String s2 = s.substring(1); // 把A转成大写 String s3 = s1.toUpperCase(); // 把B转成小写 String s4 = s2.toLowerCase(); // C拼接D String s5 = s3.concat(s4); System.out.println(s5);
// 优化后的代码 // 链式编程 /*String result = s.substring(0, 1).toUpperCase() .concat(s.substring(1).toLowerCase()); System.out.println(result);*/ } } |
案例7:将int数组拼成字符串
package 将int数组拼成字符串;
/* * 需求:把数组中的数据按照指定个格式拼接成一个字符串 * 举例: * int[] arr = {1,2,3}; * 输出结果: *"[1, 2, 3]" * 分析: * A:定义一个字符串对象,只不过内容为空 * B:先把字符串拼接一个"[" * C:遍历int数组,得到每一个元素 * D:先判断该元素是否为最后一个 * 是:就直接拼接元素和"]" * 不是:就拼接元素和逗号以及空格 * E:输出拼接后的字符串 * * 把代码用功能实现。 */ public class StringTest2 { public static void main(String[] args) { // 前提是数组已经存在 int[] arr = { 1, 2, 3 };
// 写一个功能,实现结果 String result = arrayToString(arr); System.out.println("最终结果是:" + result); }
/* * 两个明确: 返回值类型:String 参数列表:int[] arr */ public static String arrayToString(int[] arr) { // 定义一个可变长字符串 StringBuffer sb = new StringBuffer();
// 先把字符串拼接一个"[" sb = sb.append("[");
// 遍历int数组,得到每一个元素 for (int x = 0; x < arr.length; x++) { // 先判断该元素是否为最后一个 if (x == arr.length - 1) { // 就直接拼接元素和"]" sb = sb.append(arr[x]).append("]"); } else { // 就拼接元素和逗号以及空格 sb = sb.append(arr[x]).append(","); } }
return sb.toString(); } }
|
案例8:在大串中查找小串出现的次数
package 在大串中查找小串出现的次数;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
/* * 统计大串中小串出现的次数 * 举例: * 在字符串"woaijavawozhenaijavawozhendeaijavawozhendehenaijavaxinbuxinwoaijavagun" * 结果: * java出现了5次 * * 分析: * 前提:是已经知道了大串和小串。 * * A:定义一个统计变量,初始化值是0 * B:先在大串中查找一次小串第一次出现的位置 * a:索引是-1,说明不存在了,就返回统计变量 * b:索引不是-1,说明存在,统计变量++ * C:把刚才的索引+小串的长度作为开始位置截取上一次的大串,返回一个新的字符串,并把该字符串的值重新赋值给大串 * D:回到B */ public class StringTest5 { public static void main(String[] args) { // 键盘录入字符串(大串) System.out.println("请输入字符串(大串)"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String maxString = null; try { maxString = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
// 键盘录入字符串(小串) System.out.println("请输入字符串(小串)"); BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in)); String minString = null; try { minString = br2.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
// 写功能实现 int count = getCount(maxString, minString); System.out.println("Java在大串中出现了:" + count + "次"); }
/* * 两个明确: 返回值类型:int 参数列表:两个字符串 */ public static int getCount(String maxString, String minString) { // 定义一个统计变量,初始化值是0 int count = 0; int index; //先查,赋值,判断 while((index=maxString.indexOf(minString))!=-1){ count++; maxString = maxString.substring(index + minString.length()); }
return count; } } |
案例9:如何输出字符串的所有组合(不会)
package 如何输出字符串的所有组合;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
public class StringTest { public static void main(String[] args) { //键盘录入一个字符串 System.out.println("请输入一个字符串:"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = null; try { str = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
//将字符串转换成字符数组 char[] charArray = str.toCharArray(); StringBuffer sb = new StringBuffer(); //遍历字符数组 for(int i=0;i<charArray.length;i++){ pailieZuhe(charArray,0,i,sb); }
}
private static void pailieZuhe(char[] charArray, int begin, int len, StringBuffer sb) { if(len == 0){ System.out.println(sb+" "); return; }
if(begin == charArray.length){ return; } sb.append(charArray[begin]); pailieZuhe(charArray,begin+1,len-1,sb); sb.deleteCharAt(sb.length()-1); pailieZuhe(charArray,begin+1,len,sb); } }
|
输入:abc 输出:a b c ab ac bc abc