1、String类方法编程练习题:重点掌握思想
1,需求:将字符串中进行反转。abcde --> edcba
思路:1、因为反转,想到之前做个数组的反转的例子,
1、先将字符串转变为数组。
2、有了数组后直接进行头尾角标元素的位置置换即可
3、将数组转成字符串。
步骤:
1、将字符串转成数组:toCharArray();
2、对数组进行位置置换swap()
3、将数组转成字符串,用字符串构造函数就可以了。
实现代码:
Public static void main(String[] arsg)
{
String str="abcde";
Str=reverseString(str);
Sop(str);
}
//对制定字符串进行反转。接收一个反转的字符串,返回反转后的字符串。
Public static String reverseString(String str)
{
//将字符串变成字符数组。
Char[] chs=str.toCharArray();//这里对字串转成字符数组的方法应用还不是很熟悉,应该多花时间补。
//对数组进行遍历完成头尾角标元素的置换。
For(int start=0,end=chs.length-1;start
{
Swap(chs,start,end);
}
Return new String(chs);
}
//对字符串进行位置置换。Swap()
2、需求:对字符串中的字母进行排序,变成有序的字符串。
"bdacxrtq"--> "abcdqrtx";
思路:
1、先把字符串变成数组
2、对数组元素进行排序
3、将数组变成字符串
实现代码:
Public static String sortString(String str)
{
将字符串变成数组
Char[] chs=getCharArray(str);
对数组进行排序
sortCharArray(chs);
将排序后的数组变成字符串
String temp=new String(chs);
Return temp;
}
//对字符数组进行排序
Public static void sortCharArray(char[] chs)
{
For(int x=0;x
For(int y=x+1;y
{
If(chs[x]>chs[y])
Swap(chs,x .y)
}
}
}
Swap()//在此省略不写
Public static char[] getCharArray(String str)
{
Char[] chs=str.toCharArray();
Return chs;
}
3、需求:获取一个字符串在另一个字符串中出现的 次数。
"kk" "kksdfkkghkkjekkrtkk"
思路:
1、先要明确字符串中的是否有要查找的字串,如果有,应该记录该字串,的第一次出现的位置.
2、在第一位位置后,对剩余的字符串再次出现该字串查找,并获取位置,
3、以为类推,通过记录数完成字串出现次数的获取。
步骤:
1、定义计数器
2、因为每一次出现的位置不同,所以定义变量记录位置。
3、通过indexof方法获取位置,同时该方法的好处就是可以通过-1判断是否存在。
4、只要存在,就循环查找,并计数,同时要获取查找后的剩余字符串,在剩余字符串继续查找,通过substring(start)就可以了,而start的值就是查找到的角标+字串的长度。
实现代码:
Public static int getSubStringCount(String str,String key)
{
Int count=0;
Int index=0;
While((index=str.intdex(key,index))!=-1)
Index =index+key.length();
Count++;
}
Return count;
4,获取两个字符串最大相同子串。
"xcvcctvb" "tyuicctvonmyui"
思路:1、对短的字串进行判断,用第一个角标元素和最后一个角标元素,也就是0到length()-1;如果没有,则缩短范围,1到length()-1;或者0到length()-2;依次这样下去,但是判断当了length()+1时就表示没有包含的字串。发现随着字符串比较次数的增加,每次判断的次数也在递增,所以可以用到大圈套小圈的原理
实现代码:
Public static String getMaxSubString(String s1,String s2)
{
String max,min;定义两个字符串类型的变量max 和min用来记录参与比较的两个字符中那个较大的串,哪个是较小的字串。
Max=s1.,length()>s2.length()?s1:s2;
Min=s1.equals(max)?s2:s1;用来判断哪个是较小的字串。
For(int x=0;x
{
For(inty=0,z=min,length()-x;z!=min.length()+1;y++,z++)//z=min.length()-x;用来控制字串缩小的范围,z!=min.,length()+1???
{
String temp=min.substring(y,z);//获取字串
Sop(temp);//打印字串
If(max.contains(temp))//用contains方法来判断获取到字串是否在较大的串中存在。如果存在则返回这个串。
{
Return temp;
}
}
}
Return null;
}
5、对一个字符串去除两端的空格:
思路:1、首先对字符串首尾进行判断,是否为空格,怎么去判断?就是拿出元素中的某个字符进行判断。首先要对字符串进行遍历,得用到字符串的长度length()方法,然后用charAt()来判断是否包含空。
2、如果首尾没有空格的时候就要获取字符串,substring(0,length());
实现代码:
Public static StringTrim(String str)
{
Int start=0,end=str.length()-1;
While(start
Start++;
While(start
End--;
Return str.substring(start,end+1)//因为substring方法包含头不包含尾,所以要+1,保证取出来的字符串是完整的。
}
2、Ecplise中package和outline的理解:
Package:包资源管理器
1、通过该视窗我们能清晰的知道当前工作空间中所有的项目,比如day14,可以通过点击它的下拉栏目src可以知道该项目中包含的源文件,同样可以通过包的下拉栏目可以知道源文件中包含哪些包,比如cn.itcast.string.demo以及cn.itcast.string.test包。同样可以通过查看每个包里面包含的源文件。
2、可以直接在这个视窗中创建project、package、class、interface等。
3、在该视窗何总不能查看项目下的运行文件,也就是.class文件。
Outline大纲视窗:
1、通过该视窗可以知道当前代码中定义的类或者接口,还有所有的成员。
2、我们可以通过该视窗查找代码中某一个类或者成员,因为它都很有层次结构的显示出了当前源码中构成结构,比如定义了哪些方法功能函数,定义哪些成员变量,通过在该视窗中双击它,就会在源码中标示出来选定。
3、同时可以通过在该视窗中可以修改在代码中多处出现的名称。选定要要修改的右键选择refactor--rename进行修改,这样可以修改源码中所有出现的该名称的成员。还可以关联到使用到它的其他的代码中也一并修改。
3、开发技巧:
将java中已有的功能封装成我们自有的方法,这样的话方便其他人对其进行使用。
以及老师在用高级编译器的对注释小细节的用法。私有和非私有注释代码的写法。
代码实现:
4、StringBuffer
1、特点:
i. 用于存储数据的容器(数组、对象、变量)其实存储的就是一个数组,把数组进行了封装,数组是没有方法的,只有一个属性length;
ii. 该容器的长度是可变的,存储了字符串之后可以对字符串进行修改,但是字符串自身是不能修改的。
iii. 该容器可以存储基本数据类型和引用型数据类型,
注意:怎么理解可变长度数组?
当一个数组超出了指定长度数组的长度时,这时就在容器中按照一定的规则创建另一个新数组,这时新创建的数组可能是原来数组长度的一倍或者其他,这时原数组会对新数组进行赋值,把之前装进数组中的数据赋值给新数组,超出了长度的部分再在存储在后面。如果明确了要操作的字符数的话就用StringBuffer(intcapacity)明确长度的方法,这样就不用在数组中不断创建新数组了。
2、功能:
i. 添加:
1. 添加在尾部:StringBufferappend();不支持byte和short数据类型,其他的都支持,但是也可以使用,因为支持int,这样可以自动类型提升。
Eg:StringBuffersb=new StringBuffer();
StringBuffers1=sb.append("ab");
StringBuffers2=sb.append("cd");
sop(s2==sb)true
为什么?因为在stringBuffer缓冲区中始终只有一个容器。
相当于:sb.append("ab").append("cd");添加到指定的位置:
2. 添加到固定位置:
StringBuffer insert(index,data)在指定位置添加指定的数据
Eg:
sb.append("ab").append("cd").insert(1,"kk");结果akkbcd一定要注意不是abkkcd,是指定在1角标处添加,之前1角标处的元素向后顺延。
ii. 删除:
1. StringBuffer delete(int start,int end)一般情况下有头有尾的通常情况下不包含尾,
2. StringBuffer deleteCharAt(index)删除指定位置的字符。
Eg:
sb.deleteCharAt(3);//结果akkcd,B没有了。
sb.delete(1,4);acd包含1不包含4
清除缓冲区:好处:缓冲区不变,可以重复使用。
sb.delete(0,sb.length());
sb=newStringBuffer();这也是清除缓冲区的另一方式。
哪一种好?第一种把缓冲区的东西全部删除。第二种是重新创建一个空间占用内存,第一种好
sb.setLength(2);结果:ak 保留缓冲区的长度,同样可以用来清除缓冲区
sb.setLength(0);结果为空。同样可以清除缓冲区。
iii. 查找:
char CharAt(index);
int indexOf(str);
int lastIndexOf(str);
iv. 修改:
1. Void setCharAt(index,chs);修改指定位置的字符。
Eg: sb.setCharAt(2,'p');结果为akpbcd
2. StringBuffer replace(start,end,str)
Eg:sb.replace(1,3,"cctv")acctvbcd还是包含头不包含尾,把KK替代了。
3. Reverse();反转
Eg:StringBuffersb2=new StringBuffer("abcdef");
sb2.reverse();//fedcbas
3、StringBuffer和数组的区别:
a) 数组是固定长度的,字符串缓冲区是可变长度的。
b) 数组中的元素类型是固定的同一类型,字符串缓冲区是任意的,也可以是同一类型。
c) 数组对象只有一个length属性通过角标操作数组中的元素,而字符串缓冲区是通过一系列的方法对字符串进行操作。
d) 数组中的元素可以通过角标直接进行访问,而字符串缓冲区元素通常操作后要通过toString变成字符串使用。
Eg:将一个整数数组变成字符串,格式:[元素1,元素2,...]
pubic static String arrayToString(int[] arr)
{
Stringstr="";
for(int x=0;x { if(x!=arr.length-1) str=str+arr[x]+", "; else str=str+arr[x]+"]" } rteurn str; } 方法二: pubic static String arrayToString2(int[] arr) { StringBuffersb=new StringBuffer(); sb.append("["); for(int x=0;x { if(x!=arr.length-1) str=str+arr[x]+", "; else str=str+arr[x]+"]" } rteurn sb.toString(); } 总结:第二种方式,产生的字符串全部都装在了stringBuffer里面,不用产生很多的字符串,后面直接返回一个字符串就可以了。然而第一种是不断的产生新的字符串。 4、StringBuilder: 特点:是jdk1.5版本出现后的新特性,可以替代StringBuffer,但是二者是有区别的: 1、StringBuilder是线程不同步的,StringBuffer是线程同步的。 2、二者用法相同,但是StringBuilder效率较StringBuffer高。在开发单线程时用StringBuilder。 3、提高效率的原理是单线程,没有锁的机制。操作容器的方法很多,增删改查,如果一个线程在添加,一个线程在删除,这样就降低了效率,在一个添加时不能删除,此时使用的是同一个锁,只要以判断锁就在消耗资源。 实现代码: StringBuilder s1=newStringBuilder("hello"); StringBuilder S2=newStringBuilder("java"); Method(s1,s2); Method(String s1,String s2) { S1.append(s2); S1=s2; } 输出结果:hello java java 内存分析: 分析:基本步骤就不再多说,这里最主要的是,s2.append(s2),在内存中是怎么样实现的,就是说把s2的字符串内容添加到s2中,此时s1在内存中的对象值为hello java。s1=s2是指将s2的内存空间地址复制给s1此时s1指向了s2.当method方法结束后,弹栈,打印主函数中s1和s2此时s1还是指向堆内存中的s1对象值为:hello java s2指向的还是堆内存中的s2对内存中的内容为java 5、基本数据类型的对象包装类 Byte---Byte Short--Short Int----Interger Char---Character Long---Long Double-Double Float--Float boolean-Boolean 5.1把基本数据类型封装成对象的好处: 可以在对象中定义更多的属性和行为对基本数据类型进行操作。 比如:整数的范围,如果整数被封装成为对象,那么取值范围当然是对象自己最清楚。所以只要调用对象中的属性和行为即可。 5.2常见的操作:不懂,没有大概的体系?思路不清晰! 1、sop(Integer.parseInt("21")+4)//结果25 parseInt()这个方法只能往里面传的是有效的数字格式字符串。 2、对于其他的数据类型的字符串转换方式都一样的。 xxx a=Xxx.parseXx(XxxString) int a=Interger.parseInt("23"); longa=Long.parseLong("345"); booleana=Boolean.parseBoolean("true"); 有一种类型没有parse方法: Character,因为它就是字符类,不需要去转换,可以对指定的字符转成大小写。 3、怎么将整数转成字符串呢? int num=4; s=Integer.toString(num); 4、如何将一个整数数值封装成对象呢?通过构造函数。还可以通过静态方法。valueof的形式。 newInteger(4); newInteger("34353"); Integer i1=new Integer(4); Integer i2=new Integer("4"); sop(i1==i2);false 比较的是地址值 sop(i1.equals(s2));true只比较里面的数值的大小。 5、将其他进制转成十进制。 int x=Interger.parseInt("110",2);2代表的是用什么进制来解析,这里就是说110是用二进制来解析的代表6 sop(x+1);结果为7 6、怎么将整数对象转成整数呢? 使用IntValue() int y=i1.intValue(); sop(y+1);结果为5, 6、自动拆箱和自动装箱: Jdk1.5版本后对基本数据类型对象包装类进行了升级,可以像操作基本数据类型一样操作基本数据类型对象。 Eg:integer z=4; 在此4是一个对象,进行了自动装箱 Z=new Interger(4); Z=z+5;这里进行自动拆箱过程,它等价于z=new Integer(z.intValue()+5); 注意:在书写时,要注意Z可以取的值多了一个null,要对它进行判断。 实现代码: Integer m=128; Integer n=128; Integer m1=new Integer(128); integer n1=new Integer(128); m1==n1?false m=n?false 当换成127时,m==n true 为什么?如果自动装箱的数据在byte范围之内,同样的数据不再单独开辟空间。 7、练习: 1、要求:"349 -1 78 3 22"对字符串中的数值进行从小到大的排序, 变成一个数值有序的字符串。 -13 9 22 34 78 参考BaseTypeTest.java 实现代码: 思路:1、看到了排序,想到了数组 2、发现数组中的元素都在字符串中,怎么获取字符串中的这些数据呢? 3、发现这些数据之间都用空格分隔,可以通过字符串对象的方法进行分割 4、对于分割完成的字符串是一个字符串数组。 5、将字符串数组转成Int数组。 6、将对int数组进行排序。 7、将int数组变成字符串。 Public class BaseTypeTest { Private static final String SEPARATOR=" "; 这里为什么要定义常量?因为下面的代码中有几次都用""这个字符串。为了体现其专业性,以及更好的把前面学习到的知识结合起来,就将它用final修饰。 Public static void main(String[] args) { String str="34 9 -1 78 3 22"; Str=sortNumberString(str); Sop(str); } Public static String sortNumberString(String str) 1、将字符串进行切割 String[] nums=getNumberStringArray(str); 2、将字符串数组转成int数组 Int[]arr=StringArrayToIntArray(nums); 3、对int数组进行排序 sortIntArray(arr); 4、将int数组变成字符串 String temp=intArrayToString(arr); Return temp; } Public static String[] getNumberStringArray(String str) { Return str.split(SEPARATOR); } Private static int[] StringArrayToIntArray(String[] nums) { Int[] arr=new int[nums.length]; For(int x=0;x { Arr[x]=Interger.parseInt(nums[x]); } Return arr; } Priavte static void sortIntArray(int[] arr) Arrays.sort(arr); } Private static String intArrayToString(int[] arr) { StringBuilder sb=new StringBuilder(); For(iint x=0;x { If(x!=arr.length=-1) Sb.append(arr[x]+SEPARATOR); Else Sb.append(arr[x]); } Returun sb.toString(); } } 练习2: 需求:对一个字符串数组进行字典书序从小到大的排序。 {"nba","abc","cba","aaaa","z","qq"}排序前 {"aa","abc","cba","nba","qq","z"}排序后 思路: 1、既然是对数组排序,无非就是对数组中的元素进行比较,并在满足条件后进行位置 的置换。对象是不能进行大小写比较的。对象排序都用compareTo()这个方法来排基 本数值用大小于来比较。 实现代码: Publicstatic void main(String[] args) { String[] str={"nba","abc","cba","aaaa","z","qq"}; Sop(printArray(str)); sortStringArray(str); Sop(printArray(str)); } Privatestatic S说tring printArray(String[]str)//对字符串数组进行遍历。 { StringBuilder sb=new StringBuilder(); For(int x=0;x { If(x!=str.length-1)//如果不是尾角标的元素,就打印数组并且用,隔开。 Sb.append(str[x]+", "); Else Sb.append(str[x]); } Return sb.toString();//返回一个字符串。 } Publicstatic void sortStringArray(String str) { For(int x=0;x If(str[x].compareTo(str[y])>0)//这里是最重要的,对于对象的比较,我们一般都用compareTo()这个方法。 Swap(str,x,y); } } Privatestatic void swap(String[] ,int x,int y) { String temp=str[x]; Str[x]=str[y]; Str[y]=temp; } 总结:今天锁学习的内容之前没有预习,感觉听的不是很懂,尤其是基本数据类型封装对象的使用,已经查找API文档。还有就是思想不够,两个编程题自己想的和老师做的有一定的出入。问题在哪里?就是因为没有把昨天和今天学习的知识点吃透彻。明天重点复习这两天的内容,预习集合框架。
{
{