包装公司网站模板下载,wordpress header.php在哪里,怎么做手机版网站,建网站的书籍10. 认识String类 10.1 String类的重要性10.2 常用方法10.2.1 字符串构造10.2.2 String对象的比较10.2.3 字符串查找10.2.4 转化10.2.5 字符串替换10.2.6 字符串拆分10.2.7 字符串截取10.2.8 字符串的不可变性10.2.9 字符串修改 10.3 StringBuilder和StringBuffer10.3.1 String… 10. 认识String类 10.1 String类的重要性10.2 常用方法10.2.1 字符串构造10.2.2 String对象的比较10.2.3 字符串查找10.2.4 转化10.2.5 字符串替换10.2.6 字符串拆分10.2.7 字符串截取10.2.8 字符串的不可变性10.2.9 字符串修改 10.3 StringBuilder和StringBuffer10.3.1 StringBuilder的介绍10.3.2 面试题 10.4 String类oj 10.1 String类的重要性
在C语言中已经涉及到字符串了但是在C语言中要表示字符串只能使用字符数组或者字符指针可以使用标准库提供的字符串系列函数完成大部分操作但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想而字符串应用又非常广泛因此Java语言专门提供了String类。 另外在开发和校招笔试中字符串也是常客比如
字符串转整形数字字符串相加
而在面试中经常被提问 String、StringBuff和StringBuilder之间的区别等。
10.2 常用方法
10.2.1 字符串构造
常用的三种构造方法 public static void main(String[] args) {//使用常量串构造String str hello;System.out.println(str); // 调用println中print里面再调用write方法来打印//直接newString对象String str2 new String(world);System.out.println(str2);//使用字符数组进行构造char[] array {h,e,l,l,o};String str3 new String(array);System.out.println(str3);}其他方法需要使用可以去查看Java在线文档链接: String官方文档
注意
String是引用类型内部并不存储字符串本身比如在String类的是实现源码String类实例变量如下 字符串实际保存在char类型的数组即value去引用里面的数组内容而s3这个引用 指向了s1这个引用 指向的对象如下 public static void main(String[] args) {String s1 new String(hello);String s2 new String(world);String s3 s1;System.out.println(s3);}在Java中 “” 引起来也是String类型对象如 public static void main(String[] args) {String str4 ;System.out.println(输出str4);System.out.println(str4.length());System.out.println(str4.isEmpty());//为空 则为true但这里的空不是nullString str5 null;System.out.println(str5.isEmpty());//报错NullPointerException 所以null 和 不一样}10.2.2 String对象的比较
字符串的比较是常见操作之一比如字符串排序。Java中总共提供了4中方式 比较是否引用同一个对象 注意对于内置类型双等号比较的是变量中的值对于引用类型比较的是引用中的地址。 public static void main(String[] args) {int a 10;int b 20;int c 10;// 对于基本类型变量比较两个变量中存储的值是否相同System.out.println(a b); // falseSystem.out.println(a c); // true// 对于引用类型变量比较两个引用中的地址String s1 new String(hello);String s2 new String(hello);String s3 new String(world);String s4 s1;System.out.println(s1 s2); // falseSystem.out.println(s2 s3); // falseSystem.out.println(s1 s4); // true}boolean equals(Object anObject) 方法按照字典序比较 字典序字符大小的顺序 String类重写了父类Object中equals方法Object中equals默认按照比较String重写equals方法后按照 如下规则进行比较比如 s1.equals(s2) public static void main(String[] args) {String s1 new String(hello);String s2 new String(world);System.out.println(s1.equals(s2)); //String类重写了父类Object中equals方法}而父类Object中equals方法如下 public boolean equals(Object anObject) {if (this anObject) {return true;}if (anObject instanceof String) {String anotherString (String)anObject;int n value.length;if (n anotherString.value.length) {char v1[] value;char v2[] anotherString.value;int i 0;while (n-- ! 0) {if (v1[i] ! v2[i])return false;i;}return true;}}return false;}另外 public static void main(String[] args) {String s3 hello;String s4 hello;System.out.println(s3s4); // trueSystem.out.println(s3.equals(s4)); // true}int compareTo(String s) 方法
public static void main(String[] args) {String s1 new String(abc);String s2 new String(ac);String s3 new String(abc);String s4 new String(abcdef);System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1System.out.println(s1.compareTo(s3)); // 相同输出 0System.out.println(s1.compareTo(s4)); // 前k个字符完全相同输出长度差值 -3
}与equals不同的是equals返回的是boolean类型而compareTo返回的是int类型。具体比较方式
先按照字典次序大小比较如果出现不等的字符直接返回这两个字符的大小差值如果前k个字符相等(k为两个字符长度最小值)返回值两个字符串长度差值
int compareToIgnoreCase(String str) 方法与compareTo方式相同但是忽略大小写比较
public static void main(String[] args) {String s1 new String(abc);String s2 new String(ac);String s3 new String(ABc);String s4 new String(abcdef);System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同输出长度差值 -3
}10.2.3 字符串查找
字符串查找也是字符串中非常常见的操作String类提供的常用查找的方法 public static void main(String[] args) {String s1 new String(hello);//返回字符串对应下标的字符char ch s1.charAt(1);System.out.println(ch); //e//返回对应字符出现的下标位置 从头开始一个一个找 没有返回-1int index s1.indexOf(l);System.out.println(index); //2// 从指定位置3开始找某个字符出现的位置 没有返回-1int index2 s1.indexOf(l,3);System.out.println(index2); //3// 字符串查找 从一个字符串找另一个字符串 没有返回-1int index3 s1.indexOf(llo);System.out.println(index3); //2int index4 s1.indexOf(llo,3);System.out.println(index4); //-1//从后往前找返回ch第一次出现的位置没有返回-1int index5 s1.lastIndexOf(l);System.out.println(index5); //3// 从指定位置开始找从后往前找ch第一次出现的位置没有返回-1int index6 s1.lastIndexOf(l,2);System.out.println(index6); // 2// 字符串也可以从后往前同理}10.2.4 转化
结论字符串的改变 都是产生了新的对象 1.数值和字符串转化String.valueOf()方法里面可以是整数doubleboolean等 public static void main(String[] args) {//把整数 转化为 字符串String str String.valueOf(123);System.out.println(str); //这个过程 可以理解为序列化String str1 String.valueOf(new Student(张三,12));System.out.println(str1); //上面重写一下toString方法来变成想要的形式 姓名张三 年龄12//包装类首先是一个类 其次 类中拥有更多的方法 使用起来非常方便//把字符串变成整型int a Integer.parseInt(123);System.out.println(a); //123//变成double 变成什么类型就是 该包装类.parse类型double d Double.parseDouble(99.99);System.out.println(d); //99.99}2.大小写转换toUpperCase()变小toLowerCase() public static void main(String[] args) {//结论字符串的改变 都是产生了新的对象//转化成大写的时候产生了一个新的对象String str hello;String ret str.toUpperCase();System.out.println(ret); //HELLOSystem.out.println(str);String str2 HELLO;String ret2 str2.toLowerCase();System.out.println(ret2); // hello}3.字符串转数组 public static void main(String[] args) {String str hello;char[] chars str.toCharArray();for (char ch:chars) {System.out.println(ch);}4.格式化 public static void main(String[] args) {String s String.format(%d-%d-%d,2019,9,14);System.out.println(s); //2019-9-14}10.2.5 字符串替换 public static void main(String[] args) {String str abcdabcddef;// 字符替换 把a替换成AString ret str.replace(a,A);System.out.println(ret);// 字符串替换 把ab替换成AB String ret2 str.replace(ab,AB);System.out.println(ret2);}10.2.6 字符串拆分
.split(“切割符”,限制数) 拆分为几部分的数组接收 public static void main(String[] args) {String str namezhagnsanage10;String[] ret str.split();for (int i 0; i ret.length; i) {System.out.println(ret[i]);//namezhagnsan//age10}//可以加限制分割为几部分String str2 hello world hello bit;String[] ret2 str2.split( ,2);for (int i 0; i ret2.length; i) {System.out.println(ret2[i]); //hello//world hello bit}String str3 192.168.1.1;String[] ret3 str3.split(\\.);for (int i 0; i ret3.length; i) {System.out.println(ret3[i]);//192//168//1//1}注意
字符|“,”*“,”“都得加上转义字符前面加上”\ .而如果是 那么就得写成\\ .如果一个字符串中有多个分隔符可以用|作为连字符. public static void main(String[] args) {//正则表达式的分割String str 192\\168\\1\\1;String[] ret str.split(\\\\);for (int i 0; i ret.length; i) {System.out.println(ret[i]);//192//168//1//1}// 俩个分割符String str2 namezhagnsanage10;String[] ret2 str2.split(|);for (int i 0; i ret2.length; i) {System.out.println(ret2[i]);//name//zhagnsan//age//10}多次拆分 public static void main(String[] args) {//实现多次分割String str namezhagnsanage10;String[] ret str.split();// [0] namezhagnsan [1] age10for (String x:ret) {String[] s x.split();for (String ss:s) {System.out.println(ss);//name//zhagnsan//age//10}}}10.2.7 字符串截取
从一个完整的字符串之中截取出部分内容。可用方法如下 String substring(int beginIndex) 从指定索引截取到结尾 String substring(int beginIndex, int endIndex) 截取部分内容 trim() 截取字符串两边的空格 保留中间空格 public static void main(String[] args) {String str abcdef;//从指定截取到结尾String ret str.substring(3);System.out.println(ret); //def//截取部分内容 [a,b) 在Java中一般是左闭有开String ret2 str.substring(2,5); //cdeSystem.out.println(ret2);//trim() 截取字符串两边的空格 保留中间空格String str3 abcde fefef f ;String ret3 str3.trim();System.out.println(ret3); //abcde fefef f}10.2.8 字符串的不可变性
String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改对字符串的改变操作都会产生新的对象。
在被private修饰封装起来的value[] 拿不到value里面的内容而且也没有提供get 和set方法。 public static void main15(String[] args) {final char[] value {a,b,c,d};value[0] g;//修改对象 0 下标内容//value new char[10];//指向新的对象}final修饰类表明该类不想被继承final修饰引用类型表明该引用变量不能引用其他对象但是其引用对象中的内 容是可以修改的。
public static void main(String[] args) {final int array[] {1,2,3,4,5};array[0] 100;System.out.println(Arrays.toString(array));// array new int[]{4,5,6}; // 编译报错 无法为最终变量array分配值//可以修改值但是不能修改数组的指向
}为什么 String 要设计成不可变的?(不可变对象的好处是什么?)
方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.不可变对象是线程安全的.不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.
10.2.9 字符串修改
注意尽量避免直接对String类型对象进行修改因为String类是不能修改的所有的修改都会创建新对象效率 非常低下。 public static void main15(String[] args) {//String s hello;//s world; // s指向了新的指向//System.out.println(s); // 输出hello world//相当于下面String s hello;StringBuilder stringBuilder new StringBuilder();stringBuilder.append(s);s stringBuilder.toString();System.out.println(s);System.out.println(stringBuilder);}但是这种方式不推荐使用因为其效率非常低中间创建了好多临时对象。 public static void main(String[] args) {StringBuilder stringBuilder new StringBuilder(abcdef);stringBuilder.reverse();System.out.println(stringBuilder);}public static void main17(String[] args) {long start System.currentTimeMillis();StringBuffer sbf new StringBuffer();for(int i 0; i 100000; i){sbf.append(i);}long end System.currentTimeMillis();System.out.println(end - start);start System.currentTimeMillis();StringBuilder sbd new StringBuilder();for(int i 0; i 100000; i){sbd.append(i);}end System.currentTimeMillis();System.out.println(end - start);start System.currentTimeMillis();//获取当前系统的时间戳String s ;for(int i 0; i 100000; i){//以后不能在循环当中 这样去拼接字符串s i;}end System.currentTimeMillis();System.out.println(end - start);}
10.3 StringBuilder和StringBuffer
10.3.1 StringBuilder的介绍
由于String的不可更改特性为了方便字符串的修改Java中又提供StringBuilder和StringBuffer类。这两个类大 部分功能是相同的这里介绍 StringBuilder常用的一些方法其他可以点击链接: stringBuilder在线文档 public static void main(String[] args) {//StringBuilder StringBuffer 是一个可变的对象 返回的是this 也就是当前对象// 使用多线程情况下 synchronized 执行一个append方法时得先执行完才能执行其他方法// 但是频繁得上锁 和 解锁是需要耗费系统的资源StringBuffer stringBuffer new StringBuffer(aaaa);stringBuffer.append(111);System.out.println(stringBuffer); //aaaa111StringBuilder stringBuilder new StringBuilder(abcdef);stringBuilder.append(123);stringBuilder.append(456).append(789);stringBuilder.reverse(); // 逆置字符串System.out.println(stringBuilder); //987654321fedcba}StringBuff append(String str) ----- 在尾部追加相当于String的可以追加boolean、char、char[]、double、float、int、long、Object、String、StringBuff的变量char charAt(int index) ----- 获取index位置的字符int length() ----- 获取字符串的长度int capacity() ----- 获取底层保存字符串空间总的大小void ensureCapacity(int mininmumCapacity) ----- 扩容void setCharAt(int index,char ch) ----- 将index位置的字符设置为chint indexOf(String str) 返回str第一次出现的位置int indexOf(String str, int fromIndex) ----- 从fromIndex位置开始查找str第一次出现的位置int lastIndexOf(String str) ----- 返回最后一次出现str的位置int lastIndexOf(String str, int fromIndex) ----- 从fromIndex位置开始找str最后一次出现的位置StringBuff insert(int offset, String str) ----- 在offset位置插入八种基类类型 String类型 Object类型数据StringBuffer deleteCharAt(int index) ----- 删除index位置字符StringBuffer delete(int start, int end) ----- 删除[start, end)区间内的字符StringBuffer replace(int start, int end, String str) ----- 将[start, end)位置的字符替换为strString substring(int start) ----- 从start开始一直到末尾的字符以String的方式返回String substring(int startint end) ----- 将[start, end)范围内的字符以String的方式返回StringBuffer reverse() ----- 反转字符串String toString() ----- 将所有字符按照String的方式返回 public static void main(String[] args) {StringBuilder sb1 new StringBuilder(hello);StringBuilder sb2 sb1;// 追加即尾插--字符、字符串、整形数字sb1.append( ); // hellosb1.append(world); // hello worldsb1.append(123); // hello world123System.out.println(sb1); // hello world123System.out.println(sb1 sb2); // trueSystem.out.println(sb1.charAt(0)); // 获取0号位上的字符 hSystem.out.println(sb1.length()); // 获取字符串的有效长度14System.out.println(sb1.capacity()); // 获取底层数组的总大小sb1.setCharAt(0, H); // 设置任意位置的字符 Hello world123sb1.insert(0, Hello world!!!); // Hello world!!!Hello world123System.out.println(sb1);System.out.println(sb1.indexOf(Hello)); // 获取Hello第一次出现的位置System.out.println(sb1.lastIndexOf(hello)); // 获取hello最后一次出现的位置sb1.deleteCharAt(0); // 删除首字符sb1.delete(0,5); // 删除[0, 5)范围内的字符String str sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回System.out.println(str);sb1.reverse(); // 字符串逆转str sb1.toString(); // 将StringBuffer以String的方式返回System.out.println(str);}总结String和StringBuilder最大的区别在于String的内容无法修改而StringBuilder的内容可 以修改。频繁修改字符串的情况考虑使用StringBuilder。 注意String和StringBuilder类不能直接转换。如果要想互相转换可以采用如下原则:
String变为StringBuilder: 利用StringBuilder的构造方法或append()方法StringBuilder变为String: 调用toString()方法。
10.3.2 面试题
String、StringBuffer、StringBuilder的区别
String的内容不可修改StringBuffer和StringBuilder的内容可以修改StringBuffer和StringBuilder大部分功能是相似的StringBuffer采用同步处理属于多线程安全操作而StringBuilder未采用同步操作属于线程不安全操作
以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】
10.4 String类oj
链接: 第一个只出现一次的字符 public int firstUniqChar(String s) {//1.定义一个计数数组int[] count new int[26];//2.遍历字符串 记录次数for (int i 0; i s.length(); i) {char ch s.charAt(i);count[ch-a];}//3.再次遍历原字符串for (int i 0; i s.length(); i) {char ch s.charAt(i);if (count[ch -a] 1) {return i;}}return -1;}链接: 字符串最后一个单词的长度
使用split方法分割空格后的字符串 public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString s in.nextLine();String[] ret s.split( );System.out.println(ret[ret.length-1].length());}}使用lastIndexOf方法找到空格的位置然后substring截取空格1之后的字符串 public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString s in.nextLine();int index s.lastIndexOf( );String str s.substring(index1);int len str.length();System.out.println(len);}}链接: 检测字符串是否为回文 public boolean isPalindrome(String s) {s s.toLowerCase();int left 0;int right s.length()-1;while(left right) {//1.left走到合法字符底下while(leftright !isCharacterNum(s.charAt(left))) {left;}//2.right走到合法字符底下while(leftright !isCharacterNum(s.charAt(right))) {right--;}if(s.charAt(left) s.charAt(right)) {left;right--;} else {return false;}}return true;}private boolean isCharacterNum(char ch) {// if(ch a ch z || ch 0 ch 9) {// return true;// }// return false;if(Character.isDigit(ch) || Character.isLetter(ch)) {return true;}return false;}