常用对象API(String类)
StringBuffer
字符串缓冲区
★★★☆
特点&添加功能
StringBuffer
:就是字符串缓冲区。初始容量为 16 个字符。
用于存储数据的容器。
特点:
1:可以对字符串内容进行修改。
2:是一个容器。
3:是可变长度的。
4:缓冲区中可以存储任意类型的数据。
5:最终需要变成字符串。
- 和数组最大的不同:
- 数组:存储完可以单独操作每一个元素,每个元素都是独立的。
- 字符串缓冲区:所有存储的元素都被转成字符串,而且最后拼成了一个大字符串。
增删改查和可变数组长度
//1、创建一个字符串缓冲区对象,用于存储数据。
StringBuffer sb = new StringBuffer();
增删改查:C(create)U(update)R(read)D(delete)
- 添加数据。不断添加数据后,要对缓冲区中的最后的数据进行操作,必须转成字符串才可以。
sb.append("haha");//将指定数据作为参数添加到已有数据结尾处。
sb.append(true).append("hehe").append(123);//方法调用链
//String str = sb.append(true).append("hehe").append(123).toString();
//输出:run:truehehe123haha
sb.insert(2, false);//在索引位置2开始插入,包括2 (可以将数据插入到指定index位置。
//输出:run:trfalseuehehe123haha
- 删除:delete和remove
sb.delete(start,end): //删除缓冲区中的数据,包含start,不包含end。
//deleteCharAt(int index); //删除指定位置的字符。
sb.delete(1, 4);//左闭右开
//run:tlseuehehe123haha
- 修改替换:replace
StringBuffer replace(start,end,string);//左闭右开,字符串可以比start到end长
sb.replace(1, 4, "12345");
//run:t12345uehehe123haha
void setCharAt(int index, char ch) ;
- 查找
char charAt(int index)
int indexOf(String str)
int lastIndexOf(String str)
int length()
String substring(int start, int end)
- 反转:reverse
//5、反转:reverse
sb.reverse();
//run:ahah321eheheu54321t
- 将缓冲区中指定数据存储到指定字符数组中。
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
- 设置为定长(裁掉多余部分)
sb.setLength(2); //设置为定长(裁掉多余部分)
//run:ah
System.out.println(sb);
- “+”的底层过程展示
String s = "a"+5+'c';
//s = new StringBuffer().append("a").append(5).append('c').toString();
JDK1.5
版本之后出现了与StringBuffer
一模一样的对象,StringBuilder
不同的是:
StringBuffer
是线程同步。通常用于多线程。线程安全。
StringBuilder
是线程不同步。通常用于单线程。它的出现提高效率。
以后开发,建议使用StringBuilder
升级三个因素:
1,提高效率。
2,简化书写。(局限性)
3,提高安全性。
class Demo
{
}
class StringBufferDemo
{
public static void main(String[] args)
{
//method_update();
StringBuilder sb = new StringBuilder("abcdef");
char[] chs = new char[6];
sb.getChars(1,4,chs,1);//将
for(int x=0; x<chs.length; x++)
{
sop("chs["+x+"]="+chs[x]+";");
}
draw(3,6);
draw(8,9);
// StringBuilder sb1 = new StringBuilder();
// sb1.append(new Demo()).append(new Demo());
// sop("sb1="+sb1);
}
public static void method_update()
{
StringBuffer sb = new StringBuffer("abcde");
// sb.replace(1,4,"java");
sb.setCharAt(2,'k');
sop(sb.toString());
}
public static void method_del()
{
StringBuffer sb = new StringBuffer("abcde");
// sb.delete(1,3); //ae
//清空缓冲区。
//sb.delete(0,sb.length());
//sb = new StringBuffer();
// sb = replace(1,3,"nba");
// sb = setCharAt(2,'q');
// sb = setLength(10);
sb.deleteCharAt(2);
sop(sb.toString());
}
public static void method_add()
{
StringBuffer sb = new StringBuffer();
//sb.append("abc").append(true).append(34);
// StringBuffer sb1 = sb.append(34);
// sop("sb==sb1:"+(sb==sb1));
sb.insert(1,"qq");
sop(sb.toString());//abctrue34
//sop(sb1.toString());
}
public static void sop(String str)
{
System.out.println(str);
}
public static void draw(int row,int col)
{
StringBuilder sb = new StringBuilder();
for(int x=0; x<row; x++)
{
for(int y=0; y<col; y++)
{
sb.append("*");
}
sb.append("\r\n");
}
sop(sb.toString());
}
}
StringBuilder
类
JDK1.5
版本之后出现了与StringBuffer
一模一样的对象,StringBuilder
.
StringBuffer
和 StringBuilder
的区别:
StringBuffer
线程安全。
StringBuilder
线程不安全。
单线程操作,使用StringBuilder
效率高。
多线程操作,使用StringBuffer
安全。
不同的是:
StringBuffer
是线程同步。通常用于多线程。线程安全。
StringBuilder
是线程不同步。通常用于单线程。它的出现提高效率。
以后开发,建议使用StringBuilder
升级三个因素:
1,提高效率。
2,简化书写。(局限性)
3,提高安全性。
StringBuilder
练习:
数据一多找容器
容器:集合,数组,StringBuffer
等
package com.String;
public class StringBuilderTest {
public static void main(String[] args) {
int [] arr = {3,1,5,3,8};
String s = arrayToString_2(arr);
System.out.println(s);
}
/**
* 将一个int数组变成字符串
* @param arr
* @return
* 这种方式只要连接一个常量就产生新的字符串常量值值中的一个成员
*
*/
public static String arrayToString(int[] arr) {
String str = "{";
for (int i = 0; i < arr.length; i++) {
if (i != arr.length-1)
str += arr[i] + ", ";
else
str += arr[i]+"}";
}
return str;
}
/**
* //这种是不断地将字符串变成数组往StringBuilder里面装,装完一次性只打印一个字符串
* 数据一多找容器
* 容器:集合,数组,StringBuffer等
* @param arr
* @return
*/
public static String arrayToString_2(int[] arr) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length-1)
sb.append(arr[i]+", ");
else
sb.append(arr[i]+"]");
}
return sb.toString();
}
}
String
类
String类特点 :
-
String类是一个特殊的对象。
-
一旦初始化,就不可以被更改。因为是常量。
-
通过String类的构造函数可以知道,将字节数组或者字符数组转成字符串。
String s = "abc";
s = "nba"
System.out.println("s=" +s);
//nba
这里面的其实啊这是两个字符串对象,而这个s吧,它刚才指向的
abc
吧,现在指向了nba
啊,abc
没有变吧,s是一个引用型的变量,它可以指向这个,可以指向那个,但是abc
不变,String其实是一个类,
String s = "abc";
//s = "nba"
String s1 = "abc";
System.out.println(s1 = s2);// true
演示字符串定义的第一种方式,并明确字符串常量池的特点。
池中没有就建立,池中有,直接用。
String s1 = "abc";//s1是一个类类型变量, "abc"是一个对象。
//字符串最大特点:一旦被初始化就不可以被改变。
String s2 = new String("abc");
System.out.println(s1 == s2); //false
s1和s2有什么区别?
- s1在内存中有一个对象。
- s2在内存中有两个对象。
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
//String类复写了Object类中equals方法,
//该方法用于判断字符串是否相同。
String复写了equals方法,建立字符串自己的判断相同的依据
是通过字符串对象的内容来判断的
构造函数
字符串常见方法
获取
-
1、字符串是一个对象,那么它的方法必然是围绕操作这个对象的数据而定义的。
-
2、你认为字符串中有哪些功能呢?
-
2.1 获取字符串中字符的个数(长度)
int length(); // 返回此字符串的长度。空参,用this
-
2.2 根据位置获取字符
char charAt(int index); // 返回指定索引处的 char 值。 // 不存在的角标会抛出异常: java.lang.StringIndexOutOfBoundsException
-
2.3 根据字符获取在字符串中第一次出现的位置 ★★★重点掌握
int indexOf(int ch); //获取在字符串中第一次出现的位置,从零角标开始搜索 int indexOf(int ch, int fromIndex); // 返回指定字符在此字符串中第一次出现处的索引。,从指定的索引开始搜索 // 返回的索引是其中的最小值,如果最小值不存在,则返回-1 int indexOf(String ch); int indexOf(String ch, int fromIndex); //同上(字符串
从后往前:
int lastindexOf(int ch); //获取在字符串中第一次出现的位置,从末角标开始搜索 int lastindexOf(int ch, int fromIndex); // 返回指定字符在此字符串中第一次出现处的索引。,从指定的索引开始搜索 // 参数:ch - 一个字符(Unicode 代码点)。 int lastindexOf(String ch); int lastindexOf(String ch, int fromIndex); //同上(字符串
-
2.4 获取字符串中一部分的字符串,也叫子串
String substring(int beginIndex, int endIndex);//包含begin,不包含end String substring(int beginIndex);//一直到结束 // 返回一个新字符串,它是此字符串的一个子字符串。 // 该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。 // 因此,该子字符串的长度为 endIndex-beginIndex。 // 开始角标和结束角标时:100%是左闭右开的。
-
转换
-
将字符串变成字符串数组(字符串的切割)
String[] split(String regex);//涉及到正则表达式. //示例 String s = "张三,李四,王五"; String[] arr = s.split(","); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } //输出 张三 李四 王五
-
将字符串变成字符数组。
char[]toCharArray(); //示例 char[] chs = s.toCharArray(); for (int i = 0; i < chs.length; i++) { System.out.println(chs[i]); } //输出 张 三 李 四 王 五
-
将字符串变成字节数组。
byte[] getBytes(); //示例 s = "ab你"; byte[] bytes = s.getBytes(); for (int i = 0; i < bytes.length; i++) { System.out.println(bytes[i]); } //输出 97 98 -60 -29 //一个中文两个字节,而且这两个字节,最高位都是1,所以你看到的是负数
-
将字符串中的字母转成大小写。
String toUpperCase():大写 String toLowerCase():小写 //示例 System.out.println("Abc".toUpperCase()); //输出:ABC
-
将字符串中的内容进行替换
String replace(char oldch,char newch); String replace(String s1,String s2); //示例 String s1 = "java"; String s2 = s1.replace('q', 'z'); System.out.println(s1==s2);//true
-
将字符串两端的空格去除。
String trim(); //示例 System.out.println("-"+" ab c ".trim()+"-"); //输出:ab c
-
将字符串进行连接 。
String concat(string); //示例 System.out.println("abc".concat("kk"));//专业 System.out.println("abc"+"kk"); //abckk
-
String转换的有一个方法是静态方法能将基本数据类型转换成一个字符串,
这个方法是
String.valueOf
(基本数据类型)System.out.println(String.valueOf(4)+1);//专业 System.out.println(""+4+1) //简便 //41
判断
- 两个字符串内容是否相同啊?
-
boolean equals(Object obj); boolean equalsIgnoreCase(string str);//忽略大写比较字符串内容。 String s = "abc"; System.out.println(s.equals("ABC".toLowerCase())); System.out.println(s.equalsIgnoreCase("ABC")); //true true
- 字符串中是否包含指定字符串?
-
boolean contains(string str); System.out.println(s.contains("cc")); //false
- 字串是否以指定字符串开头。是否以指定字符串结尾。
-
boolean startsWith(string); boolean endsWith(string); //示例 String str = "ArrayDemo.java"; System.out.println(str.startsWith("Array")); System.out.println(str.endsWith(".java")); System.out.println(str.contains("Demo")); //是否有指定内容 //true true true
比较
public int compareTo(String anotherString)
如果参数字符串等于此字符串,则值为0 ; 一个值小于0如果这个字符串的字典比字符串参数小; 如果此字符串的字典大小超过字符串参数,则值大于0 。
System.out.println("abc".compareTo("aqz"));
//-15
注意:基本数值如果能参与比较的数值,它用的只有是大于小于这样的操作运算符,而对于对象的比较用的是方法完成的,因为对象怎么比较是不是对象自己最清楚
intern方法
intern():对字符串池进行操作的
String s1 = new String("abc");
String s2 = s1.intern();
System.out.println(s1==s2);
//false
这个intern我们怎么去理解呢:
这个new的是不是两个对象,这个abc是不是在这个new里面进行维护的啊,而这个s1.intern是不是获取池中的数据啊,这个数据是不是共享数据,如果你要是像上面这样写的话也,是不是把这个abc存到这个池里面去啊s1.intern这是不是从池里面取啊,如果池中有则返回,否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
练习
给定一个字符串数组。按照字典顺序进行从小到大的排序。
//{"nba","abc","cba","zz","qq","haha"}
/*
思路:
1,字符串变成字符数组。
2,对数组排序,选择,冒泡,Arrays.sort();
3,将排序后的数组变成字符串。
*/
class StringTest
{
public static void main(String[] args)
{
String[] arr = {"nba","abc","cba","zz","qq","haha"};
printArray(arr);
sortString(arr);
}
public static void sortString(String[] arr){
for(int i = 0; i < arr.length - 1; i++){
for(int j = i+1; j < arr.length; j++){
if(arr[i].compareTo(arr[j])>0) //字符串比较用compareTo方法
swap(arr[i],i,j);
}
}
}
private static void swapa(arr[i],int i,int j){
String temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void printArray(String[] arr){
System.out.print("{");
for(int i = 0; i < arr.length;i++){
if(i != arr.length - 1)
System.out.print(arr[i] + ", ")
else
System.out.print(arr[i]+"}");
}
}
一个子串在整串中出现的次数。
//"nbaernbatynbauinbaopnba"
/*
3,获取一个字符串在另一个字符串中出现的次数。
"abkkcdkkefkkskk"
思路:
1,定义个计数器。
2,获取kk第一次出现的位置。
3,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。
每获取一次就计数一次。
4,当获取不到时,计数完成。
*/
class StringTest2
{
/*
方法一:
此方法没判断一次就会在常量池生成一段字符串
*/
public static int getSubCount(String str,String key)
{
int count = 0;
int index = 0;
//indexof()根据字符获取在字符串中第一次出现的位置
while((index=str.indexOf(key))!=-1)
{
str = str.substring(index+key.length());
count++;
}
return count;
}
/*
方式二。
优化
*/
public static int getSubCount_2(String str,String key)
{
int count = 0;
int index = 0;
while((index= str.indexOf(key,index))!=-1)
{
index = index + key.length();
count++;
}
return count;
}
public static void main(String args[])
{
String str = "kkabkkcdkkefkks";
String key = "kk";
System.out.println("count = "+getSubCount_2(str,key) );
///System.out.println("count = "+str.split("kk").length );不建议使用。
/*将此字符串拆分为给定的regular expression的匹配。
该方法的工作原理是通过使用给定表达式和限制参数为零调用双参数split方法。
因此,尾随的空字符串不会包含在结果数组中。
**/
}
}
两个字符串中最大相同的子串。
package com.practice;
/*
4,获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。
"abcwerthelloyuiodef"
"cvhellobnm"
思路:
1,将短的那个子串按照长度递减的方式获取到。
2,将每获取到的子串去长串中判断是否包含,
如果包含,已经找到!。
*/
public class Demo {
public static void main(String[] args)
{
String s1 = "abcwerthelloyuiodef";
String s2 = "cvhellobnm";
sop("最大相同子串是:"+getMaxSubString(s2,s1));
}
/*
练习四。
*/
public static String getMaxSubString(String s1,String s2)
{
String max = "",min = "";
max = (s1.length()>s2.length())?s1: s2;
//s1 大于 s2 将 s1 赋予max,否则s2;
min = (max==s1)?s2: s1;
//不管怎样s1、s2s赋值,max都是最长的字符串
sop("max="+max);
sop("min="+min);
for(int x=0; x<min.length(); x++)
{
for(int y=0,z=min.length()-x; z!=min.length()+1; y++,z++)
{
String temp = min.substring(y,z);
// sop(temp);
if(max.contains(temp))//if(s1.indexOf(temp)!=-1)
return temp;
}
}
return "";
}
public static void sop(String str)
{
System.out.println(str);
}
}
模拟一个trim功能一致的方法。
/*
思路:
1,判断字符串第一个位置是否是空格,如果是继续向下判断,直到不是空格为止。
结尾处判断空格也是如此。
2,当开始和结尾都判断到不是空格时,就是要获取的字符串。
*/
class StringTest
{
public static void main(String[] args)
{
String s = " ab cd ";
s = myTrim(s);
System.out.println("["+s"]");
}
//去除字符串两端空格。
public static String myTrim(String str)
{
int start = 0,end = str.length()-1;
while(start<=end && str.charAt(start)==' ')
start++;
while(start<=end && str.charAt(end)==' ')
end--;
return str.substring(start,end+1);
}
}